我用这些语句来测试
float f=4.35f;
int i=(int)(f*100);
System.out.println(i);
double d=4.35;
i=(int)(d*100);
System.out.println(i);
结果是
435
434
我曾经认为float和double之间的唯一区别就在于精度。它们在计算中应该相同。但我将4.35转换为二进制,然后将其转换回十进制,发现它实际上是4.3499999 ...... 因此,如果我将它乘以100然后再进行投射,我认为答案应该是434,浮动和双重。为什么第一个是435?
答案 0 :(得分:6)
Java中的浮点使用二进制表示。许多具有十进制精确表示的数字,例如4.35
,在任何精度上都不具有二进制的精确表示(无论是float
,double
还是另一个精确表示。 / p>
当您在Java程序中编写4.35
时,它被解释为double
最接近435/100。当您写4.35f
时,它被解释为float
最接近435/100。
恰好4.35
和4.35f
都略低于435/100:
在Java中,4.35
完全代表4.3499999999999996447286321199499070644378662109375,4.35f
代表4.349999904632568359375。
在第一个近似中,两种类型中最接近的可表示值低于目标435/100的可能性很大(尽管在深入研究它时,没有任何随机性)。
另一方面,435
的数字与float
和double
完全相同。
将4.35f
或4.35
乘以100(可以完全表示为float
和double
)时,会发生以下两种可能之一:
乘法的数学结果比任何其他浮点数更接近435。然后选择435
作为操作的结果。你必须记住,Java并不知道它正在乘以4.35的数字。据他所知,你故意选择低于4.35的数字。也许你真的打算将操作数设置为4.349999904632568359375。这是乘法期间第二次近似的结果,最终结果是435.无论如何,将浮点数435
转换为int
会产生int 435
。这就是float
。
乘法的数学结果最接近435以下的浮点数。在这种情况下,选择该浮点数作为浮点乘法的结果。将此结果转换为int
会产生434
,因为从浮点到整数的转换通过截断进行。这就是double
的情况。将4.3499999999999996447286321199499070644378662109375
乘以100会产生一个接近double
435.0
以下double
的数学结果(此double
为434.99999999999994315658113919198513031005859375),因此使用此{{1}}作为浮点乘法的结果。
答案 1 :(得分:0)
除了Pascal Cuoq的优秀答案:
Multiplication of Floating Point numbers基本上由
组成在中间,当它不能用可用的23位(浮点数)或52位(双精度)精确表示时,乘以尾数的结果是舍入。
行为在Java Language Specification:
中描述Java编程语言要求浮点运算表现得好像每个浮点运算符将其浮点结果四舍五入到结果精度。不精确的结果必须四舍五入到最接近无限精确结果的可表示值;如果两个最接近的可表示值相等,则选择具有最低有效位的值。这是IEEE 754标准的默认舍入模式,称为舍入到最近的。
正如Pascal Cuoq已经说过的那样:价值4.35f
无法准确呈现。当此值乘以100.0f
时,上述意义上的结果的最接近的可表示值为435.0
。与此相反,对于4.35d
和100.0d
的乘法,结果的最接近的可表示值为434.99999999999994...
。在这两种情况下,只需省略小数部分,将值截断为int
,为435
情况产生float
的值,为{{产生434
的值1}} case,分别。