You are correct that Math.round
does not implement any of the rounding modes described in IEEE-754. These are the ones defined in IEEE-754-2008:
- TiesToEven, also known as banker's rounding (
2.5 -> 2
, 1.5 -> 2
), implemented by Math.rint
- TowardZero, also known as
trunc
, implemented in Java by casting to integer (but see footnote)
- TowardPositive, implemented by
Math.ceil
- TowardNegative, implemented by
Math.floor
- TiesToAway, rounds x.5 away from zero. This mode has no Java function but can be implemented as
Math.copySign(Math.round(Math.abs(x)), x)
(but see footnote)
From the descriptions, one might think that Math.round
is TowardPositive but that is specifically defined as the result "[…] closest to and no less than the infinitely precise result." That is clearly not the case for Math.round
, e.g. Math.round(2.3) == 2
If IEEE-754 were to define Math.round
, it would be called something like TiesTowardPositive but that does not exist in the standard.
So yes, Math.round
is not one of the IEEE-754 rounding modes, and also different from C/C++'s round
, C#'s Math.Round
, or SQL's ROUND
, for example.
I cannot tell you the reason for this choice. Of course Java is free to define additional rounding functions, choose arbitrary names for all rounding functions (IEEE-754 only describes the operation, not the name), and omit some of them as they are only "shall" and "should" requirements.
Related issues that may pop up
Footnote
Saying that TowardZero can be implemented by casting and that TiesToAway can be implemented via Math.round
is a simplification. Since these approaches convert to integer, they fail if the floating point number exceeds the integer range. Rounding 1e200, you expect the result to be 1e200 but Math.round(1e200)
will give you Long.MAX_VALUE
instead. Therefore a more complete implementation of those rounding modes first has to check the value range.