[英]java - float precision when output in console
float x = 0.98123452f;
System.out.println(x); //it prints out 0.9812345
float x = 0.98123453f;
System.out.println(x); //it prints out 0.98123455
I have no idea why the second one's output is 0.98123455 instead of 0.9812345. 我不知道为什么第二个输出是0.98123455而不是0.9812345。 Isn't the precision of float is 7 decimal digits?
浮点数的精度不是7个十进制数字吗?
To see the exact value of your float, you can use a BigDecimal:
要查看浮点数的确切值,可以使用BigDecimal:
float x = 0.98123452f; System.out.println(new BigDecimal(x));
which outputs:
0.981234490871429443359375
输出:
0.981234490871429443359375
So technically, this float:
因此,从技术上讲,该浮动:
float x = 0.981234490871429443359375f; System.out.println(new BigDecimal(x)); //prints 0.981234490871429443359375
has 24 digits precision (it was obviously cherry-picked)...
具有24位精度(显然是挑剔的)...
Forget what is above: BigDecimal only has a double constructor so there was a cast to double and the logic above is flawed. 忘记上面的内容:BigDecimal只有一个double构造函数,因此进行了强制转换为double,并且上面的逻辑存在缺陷。
Bottom line: not all numbers can be represented as a float and the gap between one float and the next one varies depending on the magnitude of the number. 底线:并非所有数字都可以表示为浮点数,一个浮点数与下一个浮点数之间的距离取决于数字的大小而变化。
The IEEE 754 float representation of IEEE 754的浮点表示形式
0.98123453
is 32 bits of (sign, exp, mantissa): 是32位(符号,exp,尾数):
0 01111110 11110110011001000110000
which is: 这是:
0.9812345504760742
in double precision, and cast back to float decimal representation: 以双精度,然后转换回浮点十进制表示形式:
0.98123455
The number of bits allocated to a single precision (float) is 32, and 64 bits for double precision. 分配给单精度(浮点数)的位数为32,而双精度则为64位。 Further note that
BigDecimal
that is frequently suggested will store your number as a string, and not in IEEE754 format. 还要注意,经常建议使用
BigDecimal
,它将您的数字存储为字符串,而不是IEEE754格式。 It will do a conversion when it needs to act on the number, and while it has a better precision, it is awfully slow. 当需要对数字进行运算时,它将进行转换,并且虽然精度更高,但速度非常慢。
EDIT. 编辑。 To clarify why it prints 0.98123455, we need to observe that it is the closest single precision representation of the number 0.98123453:
为了阐明为什么打印0.98123455,我们需要观察它是数字0.98123453的最接近的单精度表示形式:
00111111011110110011001000101111 = 0.9812345 (sp) = 0.9812344908714294 (dp)
00111111011110110011001000110000 = 0.98123455 (sp) = 0.9812345504760742 (dp)
00111111011110110011001000110001 = 0.9812346 (sp) = 0.981234610080719 (dp)
sp = single precision, dp = double precision sp =单精度,dp =双精度
The listing is for the [-1,+1] binary range around the number, and you can see that 0.98123453
is closest to the 10000
suffix of the mantissa, while 0.98123452
is closest to the 01111
suffix. 该清单是针对数字附近的[-1,+ 1]二进制范围的,您可以看到
0.98123453
最接近尾数的10000
后缀,而0.98123452
最接近后缀01111
。
isn't the precision of float is 7 decimal digits?
浮点数的精度不是7个十进制数字吗?
No. It is 23 binary digits. 否。它是23位二进制数字。 The minimum number of decimal digits that can be represented in 23 bits is therefore 6. This is not a mere 'guarantee' as stated in other answers here, it is a mathematical tautology arising from log10(2^23) = 6.92369.
因此,可以用23位表示的十进制数字的最小数目为6。这不仅仅是在此处的其他答案中所述的“保证”,它是由log10(2 ^ 23)= 6.92369引起的数学重言式。
The default output format for floating-point in Java is to print just enough digits so that conversion back to the floating-point type produces the original value. Java中浮点数的默认输出格式是仅打印足够的数字,以便转换回浮点类型时会产生原始值。
What happens in detail in your code is: 您的代码中发生的详细信息是:
0.98123452f
is converted to the float
value 0.981234490871429443359375. 0.98123452f
转换为float
值0.981234490871429443359375。 float
value to 0.9812345 is 0.981234490871429443359375. float
值是0.981234490871429443359375。 However, converting “0.981234” to float
would produce 0.981234014034271240234375, so the “5” is needed. float
将产生0.981234014034271240234375,因此需要“ 5”。 0.98123453f
is converted to the float
value 0.98123455047607421875. 0.98123453f
转换为float
值0.98123455047607421875。 An interesting consequence of this is that, if you assign a float
value to a double
object and then print the double
value, it will often display more digits than printing the float
value, even though the values are exactly the same. 有趣的结果是,如果将
float
值分配给double
对象,然后打印该double
值,则即使打印的值完全相同,也通常会比打印float
值显示更多的数字。 Because the double
format is finer (more precise) than the float
format, there may be many double
values between the value printed for float
(eg 0.9812345) and the actual value (0.981234490871429443359375). 因为
double
格式比float
格式更好(更精确),所以在为float
打印的值(例如0.9812345)和实际值(0.981234490871429443359375)之间可能会有很多double
值。 Therefore, more digits are needed to distinguish the value. 因此,需要更多的数字来区分该值。
不, float
只有六位数的十进制精度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.