当前位置: 首页 > 编程语言 > C#

为什么C#允许从Long到Float的-Long隐式-转换,这可能会丢失精度?分享

时间:2023-04-10 19:19:31 C#

为什么C#允许*Long隐式*从Long转换为Float,这可能会丢失精度?一个类似的问题LonginFloat,why?这里没有回答我要找的东西。C#标准允许从long到float的隐式转换。但是当表示为浮点数时,任何长于2^24的长度都必然会失去其“价值”。C#标准明确指出长整数到浮点数的转换可能会丢失“精度”但绝不会丢失“量级”。我的问题是关于整合的类型,“精确”和“量级”是什么意思。数字n与数字n+1完全不同,不像实数,实数3.333333和3.333329可能被认为足够接近计算(即取决于程序员想要的精度)不允许从long到float的隐式转换会引起细微的错误,因为从长远来看它会导致值“悄无声息”地丢失(作为一名C#程序员,我习惯于编译器在防范这些问题方面做得非常出色)然后C#语言设计团队背后的隐含推理允许这个转换是什么?我在这里缺少什么证明从long到float的隐式转换是正确的?一般来说,浮点数并不能准确表示很多数。就其本质而言,它们是不精确的并且容易出现精度错误。警告您浮点数始终如此并没有真正增加价值。这是一个很好的问题。你实际上可以概括这个问题,因为隐式转换也存在同样的问题:实际上,所有整数类型(甚至char!!)都有一个到float和double的隐式转换;但是,只有上面列出的转换会导致精度损失。另一个有趣的是,C#语言规范在解释“为什么没有从十进制到双精度的隐式转换”时有一个自相矛盾的论点:十进制类型比浮点类型精度更高,但范围更小。因此,从浮点类型转换为小数可能会产生溢出异常,而从小数类型转换为浮点类型可能会导致精度损失。由于这些原因,浮点类型和小数之间不存在隐式转换,如果没有显式转换,就不可能在同一个表达式中混合使用浮点和小数操作数。我认为“为什么做出这个决定”这个问题最好由EricLippert这样的人来回答。我最好的猜测......这是语言设计者没有任何强有力的论据以某种方式做事的事情之一,所以他们选择(他们认为的)更好的选择,尽管这是有争议的。在他们的辩护中,当你将一个大的long转换为一个float时,你会失去精度,但你仍然可以在浮点世界中获得该数字的最佳表示。就像把一个int转成byte,可能会溢出(整数值可能超出byte所能表示的范围),得到一个无关/错误的数字。但是,在我看来,如果他们不进行其他会导致精度损失的转换,那么从不进行从十进制到浮点数的隐式转换会更加一致。关于积分的类型,“精确”和“量级”的含义。数字n与数字n+1完全不同,不像实数,实数3.333333和3.333329可能被认为足够接近计算(即取决于程序员想要的精度)“精度”定义了一个数字可以携带多少位。如果用BCD编码(为了方便),一个字节只能携带2个十进制数字。假设您有2个字节可用。您可以使用它们以整数格式对数字0-9999进行编码,或者定义一种格式,其中最后一位数字表示十进制指数。然后您可以编码0-999*(10^0-10^9)现在您可以编码最多999000000000的数字而不是编码数字。但是,如果您将整数格式从9999转换为新格式,您只会得到9990。您已经获得了可能数字(您的)的范围,但您失去了精度。使用double和float,可以准确表示以下值:(int=32位,long=64位,全有符号?int->float-2^24-2^24int->doubleallvalueslong->float-2^24-2^24long->double-2^53-2^53不允许从long到float的隐式转换会引起细微的错误,因为它会导致long值“悄无声息”地失去它们的价值(作为C#程序员,我习惯了编译器>防止这些问题做得很好)是的,它引入了无声的错误。如果你想让编译器帮你修复它们,那就算了。你得靠自己了.我不知道有任何语言会警告不要失去精度。一个这样的错误:Arianerocket...maxlongvaluecanbeputintofloatfloat.MaxValue~=3.402823+e38long.MaxValue~=9.223372+e18即使long是64bitInteger类型,float是32bit,但是计算机处理float的做与long的工作方式不同。但是使用浮动,更大的范围是以牺牲精度为代价的。long的精度比float高很多,但是float的10^38比long10^18高一个数量级。我不认为他们错误地允许从long到float的隐式转换,因为float仍然精确到7位数字。所以如果有人需要更高的精度,他们总是可以使用double或decimal`Double-15-16bits(64bits)Decimal-28-29significands(128bits)进一步思考,似乎所有三个答案(更多更多/更少指向对同一件事)能够正确解释其中的“为什么”部分。float和long都是数字类型float范围足够大以保持长距离我认为以上两个标准足以说明longfloat转换应该是隐式的。由于float是单精度的,不能准确表示long的所有值。因此,他们将其作为标准中的事实陈述。long到float的转换是“安全的”,因为生成的float可以很容易地表示long值,但会损失精度。float到long的进一步转换不是隐式的(因为float的范围比long可以容纳的范围大得多)并且这确保不允许这样的事情默默地longlng=16777217;浮动flt=lng;//这里失去精度longlng2=flt;//如果允许,将是16777216或2^24booleq=lng==lng2;只有当可以默默地获得转换后的多头时,多头失去价值的问题才会出现。谢谢大家帮助我更好地理解。以上是C#学习教程:为什么C#允许*Long隐式*从Long到Float的转换,可能会丢失精度?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: