java 浮点数 精度,Java浮点数的显示精度

If we run the following code:

float f = 1.2345678990922222f;

double d = 1.22222222222222222222d;

System.out.println("f = " + f + "\t" + "d = " + d);

it prints:

f = 1.2345679 d = 1.2222222222222223

The long tail in the literal 1.2345678990922222 is ignored but the long tail in 1.22222222222222222222 is not (the last decimal digit in the variable d becomes 3 instead of 2). Why?

解决方案

The number of digits you see when a float or a double is printed is a consequence of Java’s rules for default conversion of float and double to decimal.

Java’s default formatting for floating-point numbers uses the fewest significant decimal digits needed to distinguish the number from nearby representable numbers.1

In your example, 1.2345678990922222f in source text is converted to the float value 1.2345678806304931640625, because, of all the values representable in the float type, that one is closest to 1.2345678990922222. The next lower and next higher values are 1.23456776142120361328125 and 1.23456799983978271484375.

When printing this value, Java only needs to print “1.2345679”, because that is enough that we can pick out the float value 1.2345678806304931640625 from its neighbors 1.23456776142120361328125 and 1.23456799983978271484375.

For your double example, 1.22222222222222222222d is converted to 1.22222222222222232090871330001391470432281494140625. The next lower and next higher values representable in double are 1.2222222222222220988641083749826066195964813232421875 and 1.2222222222222225429533182250452227890491485595703125. As you can see, to distinguish 1.22222222222222232090871330001391470432281494140625 from its neighbors, Java needs to print “1.2222222222222223”.

Footnote

1 The rule for Java SE 10 can be found in the documentation for java.lang.float, in the toString(float d) section. The double documentation is similar. The passage, with the most relevant part in bold, is:

Returns a string representation of the float argument. All characters mentioned below are ASCII characters.

If the argument is NaN, the result is the string "NaN".

Otherwise, the result is a string that represents the sign and magnitude (absolute value) of the argument. If the sign is negative, the first character of the result is '-' ('\u002D'); if the sign is positive, no sign character appears in the result. As for the magnitude m:

If m is infinity, it is represented by the characters "Infinity"; thus, positive infinity produces the result "Infinity" and negative infinity produces the result "-Infinity".

If m is zero, it is represented by the characters "0.0"; thus, negative zero produces the result "-0.0" and positive zero produces the result "0.0".

If m is greater than or equal to 10-3 but less than 107, then it is represented as the integer part of m, in decimal form with no leading zeroes, followed by '.' ('\u002E'), followed by one or more decimal digits representing the fractional part of m.

If m is less than 10-3 or greater than or equal to 107, then it is represented in so-called "computerized scientific notation." Let n be the unique integer such that 10n ≤ m < 10n+1; then let a be the mathematically exact quotient of m and 10n so that 1 ≤ a < 10. The magnitude is then represented as the integer part of a, as a single decimal digit, followed by '.' ('\u002E'), followed by decimal digits representing the fractional part of a, followed by the letter 'E' ('\u0045'), followed by a representation of n as a decimal integer, as produced by the method Integer.toString(int).

How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x, then f must be one of them and the least significant bit of the significand of f must be 0.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值