Why does Math.round(0.49999999999999994) return 1

The answer hereafter is an excerpt of an Oracle bug report 6430675 at. Visit the report for the full explanation.

The methods {Math, StrictMath.round are operationally defined as

(long)Math.floor(a + 0.5d)

for double arguments. While this definition usually works as expected, it gives the surprising result of 1, rather than 0, for 0x1.fffffffffffffp-2 (0.49999999999999994).

The value 0.49999999999999994 is the greatest floating-point value less than 0.5. As a hexadecimal floating-point literal its value is 0x1.fffffffffffffp-2, which is equal to (2 - 2^52) * 2^-2. == (0.5 - 2^54). Therefore, the exact value of the sum

(0.5 - 2^54) + 0.5

is 1 - 2^54. This is halfway between the two adjacent floating-point numbers (1 - 2^53) and 1. In the IEEE 754 arithmetic round to nearest even rounding mode used by Java, when a floating-point results is inexact, the closer of the two representable floating-point values which bracket the exact result must be returned; if both values are equally close, the one which its last bit zero is returned. In this case the correct return value from the add is 1, not the greatest value less than 1.

While the method is operating as defined, the behavior on this input is very surprising; the specification could be amended to something more like "Round to the closest long, rounding ties up," which would allow the behavior on this input to be changed.

首页 - Wiki
Copyright © 2011-2024 iteam. Current version is 2.125.0. UTC+08:00, 2024-05-04 12:42
浙ICP备14020137号-1 $访客地图$