-1

It seems like the smallest non-zero number that google's calculator can calculate is 2^-1023. I.e. 2^-1024 equal 0.

In JAVA Double.MIN_VALUE is 2^-1074.

When reading about JAVA's Double.MIN_VALUE here and across the Internet there are many mentions of IEEE 754 but none of them actually says that 2^-1074 is the smallest non zero number that is defined in IEEE 754.

So my questions are:

  1. How does JAVA's Double.MIN_VALUE relate to IEEE 754's definition of the smallest non-zero number? Is there such a thing at all?
  2. Why does Google's calculator cannot calculate smaller numbers than 2^-1023 when apparently there are such numbers? (I know people don't use them every day but still, programming languages allow it)
  3. In JAVA, if Double.MIN_VALUE == 4.9E-324 then why (Double.MIN_VALUE + Double.MIN_VALUE) == 1.0E-323 and not 9.8E-324, considering that (4.9E-5 + 4.9E-5) == 9.8E-5?
  4. How much should I add to Double.MIN_VALUE in order to make it equal zero?

Here is the program I made on these questions:

public class Lecture {
    public static void main(String[] args) {

        double min = Double.MIN_VALUE;
        double max = Double.MAX_VALUE;
        double minPlusOne = min + 0.0001;
        System.out.println("Min + 1: " + minPlusOne);
        System.out.println("Double.MIN_VALUE: " + min);
        System.out.println("Double.MIN_VALUE: " + max);
        double myMin = Math.pow(2, -1074);
        System.out.println("2^-1074: " + myMin);
        System.out.println("Double.MIN_VALUE == 2^-1074: "  + (min == myMin));
        System.out.println();

        System.out.println("Changed Min:" + (min + min));

        double a = 4.9E-5;
        double b = a + a;
        System.out.println(b);

    }
}

EDIT: As asked, removing the follow up questions.

paradox
  • 634
  • 5
  • 13
  • 1
    The google calculator cannot calculate `2^-1074` only if entered within the search engine. If I open the calculator (by entering "2+2" as the search term) I can enter "2^-1074" as expression and it dutifully reports "5e-324" (using slightly different rounding from java) – Thomas Kläger Feb 24 '19 at 08:09
  • Please do not edit additional questions into a question. Ask new questions instead. However, your first extra question is due to the normal rounding that occurs in floating-point operations. Your second extra question is not phrased clearly. The relationship of `Integer.MAX_VALUE` to `Integer.MIN_VALUE - 1` is largely happenstance due to how they are encoded, and the floating-point encoding does not lend itself to this. – Eric Postpischil Feb 24 '19 at 13:47

3 Answers3

1

How does JAVA's Double.MIN_VALUE relate to IEEE 754's definition of the smallest non-zero number? Is there such a thing at all?

You should carefully read a good tutorial on FP numbers for instance what every programmer should know about floating point arithmetic. "Normal" numbers min value is 2^-1023. But IEEE-754 also has "subnormal" (or denormal) numbers whose min value is 2^-1074. These numbers can be smaller but with an important loss of precision.

Why does Google's calculator cannot calculate smaller numbers than 2^-1023 when apparently there are such numbers? (I know people don't use them every day but still, programming languages allow it).

Not all hardware support denormal numbers, and when it is supported using these numbers come with a high temporal cost (for instance on a pentium operator latency for normal numbers is ~5, but can be >100 if the result or one operand is subnormal). That may be the reason why google does not support subnormals (but it is just an hypothesis). FP libraries and hardware have a mean to consider subnormals numbers as zero.

In JAVA, if Double.MIN_VALUE == 4.9E-324 then why (Double.MIN_VALUE + Double.MIN_VALUE) == 1.0E-323 and not 9.8E-324, considering that (4.9E-5 + 4.9E-5) == 9.8E-5?

The printed value is rounded and displayed in binary. Exact value of integer part of 2^-1023 has much more decimals than 4.9. and it is the same for its double. It is a matter of display.

How much should I add to Double.MIN_VALUE in order to make it equal zero?

Just subtract it for itself.

Alain Merigot
  • 10,667
  • 3
  • 18
  • 31
  • What you say becomes even more obvious when I tried it out with `BigDecimal`. So, when I added the following to my program, I see how it works: `BigDecimal myBigDecimal = new BigDecimal(min + min); ` – paradox Feb 24 '19 at 08:29
  • Smallest positive normal number is actually 2^-1022, not 1023 (see Double.MIN_NORMAL doc in Java or https://en.wikipedia.org/wiki/IEEE_754-1985#Double_precision). – Alexey Romanov Feb 24 '19 at 21:19
0
  1. Instead of "reading here and across the Internet", it's enough to look at the Javadoc:

    A constant holding the smallest positive nonzero value of type double... and also equal to Double.longBitsToDouble(0x1L).

    I.e. its last bit is 1 and the rest are 0.

  2. 2^-1023 isn't actually the minimal value there, you can get Double.MIN_VALUE as (2^-1023)/2^51. No idea why Google's developers made 2^-1024 return 0, you'd have to ask them.

  3. Double.MIN_VALUE is, as documented, 2^-1074. It is not equal to 4.9*10^-324, it's just printed like this according to the specification of Double#toString. Rounding for Double.MIN_VALUE and for 2*Double.MIN_VALUE just happens to go in different directions.

  4. -Double.MIN_VALUE, just as for any other Double d you'd add -d.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
-1

Instead of "reading and across the internet" you could have entered these search terms into any search engine:

IEEE 754 1074

And you could have found the following articles on Wikipedia that explain it well:

https://en.wikipedia.org/wiki/IEEE_754-1985#Double_precision:

Double precision Double-precision numbers occupy 64 bits. In double precision:

  • The positive and negative numbers closest to zero (represented by the denormalized value with all 0s in the Exp field and the binary value 1 in the Fraction field) are

    ±2^−1074 ≈ ±4.94066×10^−324

  • The positive and negative normalized numbers closest to zero (represented with the> binary value 1 in the Exp field and 0 in the fraction field) are

    ±2^−1022 ≈ ±2.22507×10^−308

  • The finite positive and finite negative> numbers furthest from zero (represented by the value with 2046 in the Exp field and all 1s in the fraction field) are

    ±(1−2^−53) × 2^1024 ≈ ±1.79769×10^308

https://en.wikipedia.org/wiki/IEEE_754#Basic_and_interchange_formats:

Note that in the table above, the minimum exponents listed are for normal numbers; the special subnormal number representation allows even smaller numbers to be represented (with some loss of precision). For example, the smallest positive number that can be represented in binary64 is 2^−1074 (because 1074 = 1022 + 53 − 1).

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34