Floating point operations ambiguity
Possible Duplicate:
Why is floating point arithmetic in C# imprecise?
为什么浮点运算存在偏差?有什么具体原因吗?输出:一百六十一百三十九
1 2 3 4 5 6 7 8 9 10 | static void Main() { float x = (float) 1.6; int y = (int)(x * 100); float a = (float) 1.4; int b = (int)(a * 100); Console.WriteLine(y); Console.WriteLine(b); Console.ReadKey(); } |
任何有理数的分母不是2的幂,当用二进制表示时,都会导致无穷多的数字。这里有8/5和7/5。因此,没有确切的二进制表示形式作为浮点数(除非您有无限的内存)。
1.6的精确二进制表示是110011001100110011001100110011001100…1.4的精确二进制表示是1011001100110011001100110011001100110011…两个值的位数都是无限的(1100是无限重复的)。
浮点值的精度为24位。因此,任何值的二进制表示都将四舍五入为24位。如果将给定值四舍五入为24位,则得到:1.6:11001100110011001101(十进制13421773)-向上取整1.4:101100110011001100110011(十进制11744051)-四舍五入
两个值的指数均为0(第一位为2^0=1,第二位为2^-1=0.5等)。因为24位值中的第一位是2^23,所以可以通过将24位值(13421773和11744051)除以2 23次来计算精确的十进制值。数值为:1.60000002384185791015625和1.399999976158141208984375。
使用浮点类型时,必须始终考虑其精度是有限的。可以精确写入十进制值的值在表示为二进制时可能向上或向下取整。强制转换为int并不考虑这一点,因为它会截断给定的值。你应该总是使用类似math.round的东西。
如果你真的需要一个有理数的精确表示,你需要一个完全不同的方法。因为有理数是分数,所以可以使用整数来表示它们。下面是一个如何实现这一目标的例子。但是,您不能编写Rational X=(Rational)1.6。你必须写一些东西,比如RationalX=New Rational(8,5)(或者New Rational(16,10)等等)。
这是因为浮点运算不精确。当您将
在输出1.6的情况下,浮点表示实际上可能比1.6小,因此当乘以100时,总数略大于160,因此整数转换给出了您所期望的结果。事实上,在计算机中,没有足够的精度来精确存储每一个实数。
有关从浮点到整数类型的转换的详细信息,请参阅此链接http://msdn.microsoft.com/en-us/library/aa691289%28v=vs.71%29.aspx-它有自己的部分。
浮点类型
但是,您可以使用
考虑使用