如果我创建一个双精度变量并为其分配一个表达式,例如 (5d/3d( 并显式转换为浮点数,例如,
double c = (float)(5d / 3d);
System.out.println(c);
输出:
1.6666666269302368
它应该给出浮点数据类型的精度,因为浮点小于双倍,所以双变量在存储浮点值方面应该没有问题,但输出是荒谬的。为什么会这样?
请帮助我理解此代码的输出。我无法理解代码中的此输出。
这是因为当你除以五和三时位模式的排列方式,它是一个不精确的浮点值(它是1.6666666
和一点点(。就这么简单。为了证明,
float f = (float) (5.0 / 3);
System.out.printf("%f=%s %s=%s%n", f, Float.toHexString(f),
(double) f, Double.toHexString(f));
System.out.printf("%s=%s %s=%s%n", f, Float.toHexString(f),
(double) f, Double.toHexString(f));
输出为
1.666667=0x1.aaaaaap0 1.6666666269302368=0x1.aaaaaap0
1.6666666=0x1.aaaaaap0 1.6666666269302368=0x1.aaaaaap0
在这两种情况下,您都会注意到位模式是恒定的。
我的Java技能非常生疏,但我认为这里发生的事情是,当你将除法的结果投射到float
时,你扔掉了一半的精度。 然后,当您将其存储在double
中并将其传递给System.out.println
时,System.out.println
尝试将其打印到无数的小数位。
但是,由于演员阵容的原因,这些小数位是不准确的。 实际上,System.out.println
发明了它们。 尝试移除铸件,看看你得到了什么,或者将结果打印为float
。 做任何一种都应该产生更明智的结果。