1

Background: I am reading "How Numbers Work" in the book How JavaScript Works by Douglas Crockford.

A number in JavaScript is represented as number = sign * coefficient * (2 ** exponent). I understand this but then there is a function deconstruct to represent an integer using the sign, coefficient, and exponent.

In order to find the exponent, the initial value is taken as -1128

which is the exponent of 'Number.MIN_VALUE' minus the number of bits in the significand minus the bonus bit.

function deconstruct(number) {
   // .....
   exponent = -1128;
   let reduction = coefficient;
   while (reduction !== 0) {
   // .....
}

Why is exponent = -1128? I did not get the reason for starting with this number, please help me in understanding this.

The complete deconstruct function as mentioned in the book.

A similar question is asked here but I did not understand the answer.

Darshna Rekha
  • 1,069
  • 7
  • 20
  • 1
    In IEEE 754 math, the exponents are "biased" as described in what you're reading. – Pointy Jan 02 '22 at 20:23
  • Do you understand what the three parts that he mentions in the comment, and their values, are? – Bergi Jan 02 '22 at 20:35
  • @Bergi If I understood correct - first the number in JS is float64 with 1 sign bit, 11 exponent bits and the rest are significant bits. A floating-point number is expressed as `number = sign * significand * base ** exponent`. In order to explain the 0.1 + 0.2 we are creating a function to find these parts but for integers. Please correct me if I am missing something. – Darshna Rekha Jan 02 '22 at 20:42
  • 1
    Yes, that's 64bit floating point numbers. But I meant specifically what are "*exponent of 'Number.MIN_VALUE'*", the "*number of bits in the significand*" and the "*bonus bit*"? – Bergi Jan 02 '22 at 20:45
  • 1
    Also you need to consider that `Math.MIN_VALUE` is a [subnormal number](https://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number) – Bergi Jan 02 '22 at 20:47
  • @Bergi No, I did not understand them. Can you help with the explanation? – Darshna Rekha Jan 02 '22 at 20:48
  • 53 significand bits consists of the bonus bit. – Darshna Rekha Jan 02 '22 at 20:54
  • 1
    Wow, it's been more obscure and tangled than I thought – Bergi Jan 02 '22 at 23:22

1 Answers1

1

I think Crockford chose this value so that the resulting coefficient is always a 53-bit integer.

The deconstruct function determines the exponent by repeatedly dividing by two, and counting how long it takes to reach 0. For the number 1, which has an exponent of 0 (for a coefficient of 1.0), it takes 1075 steps, so by starting at -1075 and counting up we'd arrive at the exponent of 0. However, to get the long coefficient, we want to arrive at an exponent of -53, so we have to start at -1128 already.

Another way to put it: Number.MIN_VALUE, which is 1 * 2**-1074, needs to be multiplied by 2 1074 times to arrive at 1, then some more times to get the long coefficient.

Notice there are multiple off-by-one mistakes to be made here:

  • to get the value 1 (a 1-bit integer) as a 53-bit integer, we need an exponent of -52 not -53
  • the loop to compute the exponent overshoots by 1 as it reaches 0
  • of the 53 significant bits, only 52 bits are stored in the significand, there's a hidden implicit 1 bit (for normal numbers)

And Crockford actually made one of them! If you check out the maths, 1074 (exponent of MIN_VALUE) + 52 (significand binary digits) + 1 ("bonus bit", whatever that refers to) amounts to 1127, not 1128. Calling the deconstruct function will return a .coefficient with 54 binary digits, which is one too many.

That said, I think even the goal is questionable. Having the coefficient, which is actually a fractional number starting with 1.…, represented as an integer may be excused as a teaching device for the book. But it doesn't make any sense to represent subnormal numbers (whose coefficients are fractional numbers 0.…) as numbers larger than 252, with barely any significant digits.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375