14

I'm interested if Java is using IEEE 754 standard for implementing its floating point arithmetic. Here I saw this kind of thing in documentation:

operation defined in IEEE 754-2008

As I understand positive side of IEEE 754 is to increase precision of floating point arithmetics so if I'll use double or float in Java would presision of computations be same as in BigDecimal? And if not than what's the point of using IEEE 754 standard in Math class?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
GROX13
  • 4,605
  • 4
  • 27
  • 41

1 Answers1

21

I'm interested if Java is using IEEE 754 standard for implementing it's floating point arithmetic.

IEEE-754 defines standards for multiple floating-point types. For many years, they were all binary floating point; that's what Java's float and double are: float is a 32-bit IEEE-754 binary floating point value (what the standard calls binary32). double is a 64-bit one (what the standard calls binary64). These binary floating point numbers are very efficient for computers to calculate, but because they work in binary and we work in decimal, there are some expectation mismatches; for instance, 0.1 cannot be stored precisely in a double, and you get oddities like 0.1 + 0.2 turning out to be 0.30000000000000004. See Is floating point math broken? for details. They're not a good choice for financial calculations, for instance.

BigDecimal is a Java class that implements decimal fractional numbers with arbitrary precision. It's much slower than using double, but the results fit with our decimal-minded expectations (for instance, that 0.1 + 0.2 will be 0.3).

The 2008 edition of IEEE-754 adds significant new formats, in particular decimal32, decimal64, and decimal128. These are decimal floating point, and so they work the same way that we do. 0.1 can be accurately stored in a decimal64. 0.1 + 0.2 is 0.3 in decimal64. However, as far as I can tell, they aren't really relevant to your question.

Since BigDecimal predates IEEE-754 2008 (by some margin), it defines its own semantics.

And if not than what's the point of using IEEE 754 standard in Math class?

JDK9 adds new operations to Math that do things defined by the IEEE-754 2008 spec (such as fma, which does a fused multiply-add), and so it defines those operations with reference to the IEEE-754 2008 spec, for clarity.

More reading:

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Does the semantics of `BigDecimal` differ from `decimalxx` when a precision is specified? E.g., does `new BigDecimal("0.1", MathContext.DECIMAL64)` differ from `decimal64`? – Safron Jan 04 '22 at 15:29
  • @Safron - I've never gone deep into the semantics of either of them, but yes, I *suspect* so given that `BigDecimal` defines an immutable object type with methods, and the IEEE-754 `decimalXX` types are primitives. They may well have different default rounding behaviors, etc., esp. as `BigDecimal`'s are configurable per instance. – T.J. Crowder Jan 04 '22 at 15:46
  • @TJCrowder I suspected something like that, but it seems we were both wrong. :) From the documentation of `DECIMAL64`: *A MathContext object with a precision setting matching the precision of the IEEE 754-2019 decimal64 format, 16 digits, and a rounding mode of HALF_EVEN.* (see https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/MathContext.html#DECIMAL64) – Safron Jan 06 '22 at 19:57
  • @Safron - That's just precision, not semantics. :-) – T.J. Crowder Jan 07 '22 at 07:41
  • 1
    @TJCrowder You're right, it seems I was a bit too fast. I found the actual semantic differences in the documentation of Java 17. See section "Relation to IEEE 754 Decimal Arithmetic" in https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html – Safron Jan 07 '22 at 11:07