53

What's the difference between Double.MIN_NORMAL (introduced in Java 1.6) and Double.MIN_VALUE?

Community
  • 1
  • 1
Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

3 Answers3

34

The answer can be found in the IEEE specification of floating point representation:

For the single format, the difference between a normal number and a subnormal number is that the leading bit of the significand (the bit to left of the binary point) of a normal number is 1, whereas the leading bit of the significand of a subnormal number is 0. Single-format subnormal numbers were called single-format denormalized numbers in IEEE Standard 754.

In other words, Double.MIN_NORMAL is the smallest possible number you can represent, provided that you have a 1 in front of the binary point (what is referred to as decimal point in a decimal system). While Double.MIN_VALUE is basically the smallest number you can represent without this constraint.

aioobe
  • 413,195
  • 112
  • 811
  • 826
14

IEEE-754 binary64 format:

s_eee_eeee_eeee_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm_mmmm

(1 s; 3×4−1 =11 es; 64−3×4 =52 ms)

, and its algorithm:

  • If e >000_0000_0000 and <111_1111_1111: interpret as (-1)s ×2e−balancer:1023 ×(base:1 +m×2−sub-one-pusher:52). (These are the normal numbers.)

  • If e =000_0000_0000: do the same (as line above) except base:1 is base:0, and e is e +1. (These are the subnormal numbers, except for zero which is neither subnormal/normal.)

  • If e =111_1111_1111 and m =0000...0000: interpret as (-1)s × infinity.

  • If e =111_1111_1111 and m <>0000...0000: interpret as NaN. (Btwbtw: therefore there're 2× (252 −1) different bit representations for NaN, cf #Quiet NaN &doubleToRawLongBits.)

Thus:

  • The smallest of its possible positive numbers is 0_000_0000_0000_0000_..._0001 (Double.MIN_VALUE (also .NET's Double.Epsilon)) (a subnormal number).

  • The smallest of its possible positive normal numbers is 0_000_0000_0001_0000_..._0000 (Double.MIN_NORMAL).


Appendix:

MIN_VALUE computation:

         (-1)s:0 ×2(e:0+1)−balancer:1023 ×(base:0 +m:1 ×2−sub-one-pusher:52)

      = 1 ×2−1022 ×2−52

      = 2−1074 (~4.94 × 10−324)

, and MIN_NORMAL computation:

         (-1)s:0 ×2e:1 −balancer:1023 ×(base:1 +m:0 ×2−sub-one-pusher:52)

      = 1 ×2−1022 ×1

      = 2−1022 (~2.225 × 10−308)

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • I think you want `2^{1 + 52} - 2` for the number of NaN bit patterns. – Mark Dickinson Aug 24 '14 at 17:10
  • And a nitpick: zero isn't a subnormal, so the "These are the subnormal numbers." statement isn't quite accurate. How about "These are the subnormal numbers and zeros." instead? – Mark Dickinson Aug 24 '14 at 17:18
  • 1
    Well, there are two cases where `m == 0`: one with `s == 0`, and one with `s == 1`. Put another way, for a NaN bit pattern, there are `2` possibilities for `s`, only one for `e`, and `2^52 - 1` for `m`; multiplying gives `2 * (2^52 - 1) = 2^53 - 2` overall possibilities. – Mark Dickinson Aug 24 '14 at 17:53
  • @MarkDickinson, why isn't zero subnormal? Looks like it fits the definition to me: it has a 0 in front of the binary point, and the exponent bits are all zero. – aioobe Mar 18 '19 at 02:15
  • @aioobe Which definition are you looking at? IEEE 754's definitions section says: "2.1.51 subnormal number: In a particular format, a non-zero floating-point number with magnitude less than the magnitude of that format’s smallest normal number. [...].", and also in the definition of "normal number" (2.1.38): "In this standard, zero is neither normal nor subnormal." – Mark Dickinson Mar 18 '19 at 07:47
3

For simplicity, the explanation will consider just the positive numbers.

The maximum spacing between two adjacent normalized floating point numbers 'x1' and 'x2' is 2 * epsilon * x1 (the normalized floating point numbers are not evenly spaced, they are logarithmically spaced). That means, that when a real number (i.e. the "mathematical" number) is rounded to a floating point number, the maximum relative error is epsilon, which is a constant called machine epsilon or unit roundoff, and for double precision it has the value 2^-52 (approximate value 2.22e-16).

The floating point numbers smaller than Double.MIN_NORMAL are called subnormals, and they are evenly filling the gap between 0 and Double.MIN_NORMAL. That means that the computations involving subnormals can lead to less accurate results. Using subnormals allows a calculation to lose precision more slowly when the result is small.

Andrei Bozantan
  • 3,781
  • 2
  • 30
  • 40