4

I read the IEEE754 rounding rules from wiki: https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules

And there is a example: In mode 'to nearest, ties away from zero', −12.5 should be -13.0

But java Math.round(-12.5)==-12.0.

And I'm sure Math.round not using mode 'to nearest, ties to even', because Math.round(-11.5)==-11.0

Actually, in Java Doc, it says "Returns the closest long to the argument, with ties rounding to positive infinity."

So, Java Math.round not conform to the IEEE 754 standard, is it correct?

Eric
  • 655
  • 2
  • 9
  • 16

1 Answers1

3

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:

  1. TiesToEven, also known as banker's rounding (2.5 -> 2, 1.5 -> 2), implemented by Math.rint
  2. TowardZero, also known as trunc, implemented in Java by casting to integer (but see footnote)
  3. TowardPositive, implemented by Math.ceil
  4. TowardNegative, implemented by Math.floor
  5. 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.

Homer512
  • 9,144
  • 2
  • 8
  • 25
  • Re “You are correct, Java's `round()` is different from IEEE's or C/C++'s, for example.”: How is Java’s `round()` different from IEEE 754’s round toward +∞? – Eric Postpischil Aug 18 '23 at 13:17
  • @EricPostpischil I checked the standard and if I'm not mistaken, that's `ceil`, which is different from Java's `round`. The standard says that the result of "round towards +inf" is the value "closest to and no less than the infinitely precise result". That wouldn't be consistent with Java's `Math.round(1.2) == 1` – Homer512 Aug 18 '23 at 15:13
  • The standard specifies nothing about what names are used, just about what formats are used and how operations behave. There is nothing in the standard that says an asterisk character corresponds to multiplication or that you have to use particular English names for operations. Each implementation of IEEE 754 may use its own binding from its terminology or syntax to IEEE 754 formats and operations. One of the operations specified in IEEE 754 is called `roundToIntegralTowardPositive` in IEEE 754, but programming languages do not have to call it that. – Eric Postpischil Aug 18 '23 at 15:16
  • Looking at it more closely, though, none of the rounding modes specified in IEEE 754 are round to nearest with ties toward +∞. There is round toward +∞ (always, not just ties) and round to nearest with ties to even low digit or ties to away from zero, but not with ties toward +∞. So that is not a rounding mode specified in IEEE 754. However, neither does it by itself break conformance with IEEE 754, as there is no requirement in IEEE 754 that an operation named `round` perform any particular rounding. – Eric Postpischil Aug 18 '23 at 15:22
  • @EricPostpischil Yeah, it's a confusing slight difference. All the conversion clauses in IEEE-754 are "shall" so I guess no matter how much Java deviates, it would still conform. Also, casting to int is `convertToIntegerTowardZero`. That part is correct – Homer512 Aug 18 '23 at 15:30