C#学习教程:为什么我的号码被错误地舍入?分享


为什么我的号码被错误地舍入?

这感觉就像那种只在现场失败的代码,但我会尝试将其改编成代表我所看到的代码片段。

float f = myFloat * myConstInt; /* Where myFloat==13.45, and myConstInt==20 */ int i = (int)f; int i2 = (int)(myFloat * myConstInt); 

单步执行代码后,i == 269,i2 == 268。 这里有什么可以解释这个差异?

浮动数学运算的精度可以高于公布的精度。 但是只要将它存储在浮点f中,就会失去额外的精度。 在第二种方法中你没有失去那种精度,当然,你将结果转换为int。

编辑:请参阅此问题为什么在由parantheses分隔和由语句分隔时C#中的浮点精度会有所不同? 为了比我可能提供的更好的解释。

因为浮点变量不是无限精确的 。 如果您需要这种准确性,请使用小数。

不同的舍入模式也可能会解决这个问题,但准确性问题是你在这里遇到的问题,AFAIK。

浮点的精度有限,基于二进制而不是十进制。 十进制数13.45无法以二进制浮点精确表示,因此向下舍入。 乘以20进一步夸大了精度的损失。 此时你有268.999 … – 而不是269 – 因此转换为整数截断为268。

要舍入到最接近的整数,可以尝试在转换回整数之前添加0.5。

对于“完美”算术,您可以尝试使用Decimal或Rational数字类型 – 我相信C#都有两个库,但我不确定。 然而,这些会更慢。

编辑 – 到目前为止我找到了一个“十进制”类型,但不是理性的 – 我可能错了。 十进制浮点是不准确的,就像二进制一样,但它是我们习惯的那种不准确,所以它给出了不太令人惊讶的结果。

用。。。来代替

 double f = myFloat * myConstInt; 

看看你是否得到了同样的答案。

我想提供一个不同的解释。

这是代码,我已经注释了(我查看内存来剖析浮点数):

   float myFloat = 13.45;  //在二进制文件中是1101.01110011001100110011   int myConstInt = 20;   float f = myFloat * myConstInt;  //二进制正好是100001101(十进制269)   int i =(int)f;  //将浮动269变为int 269  - 毫无意外   int i2 =(int)(myFloat * myConstInt); //“额外精度”导致舍入到268 

让我们仔细看看计算结果:

更新:我提炼了我的答案并撰写了一篇名为“ 浮动不像浮点​​数”的完整文章

上述就是C#学习教程:为什么我的号码被错误地舍入?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/ckf/1031894.html

发表评论

邮箱地址不会被公开。 必填项已用*标注