I could use the help of somebody who understands the binary structure of doubles better than I do. With the following code:
Var BigNumber As Double = 999999999999999999 // 18 9's
Why does the value in BigNumber
become 1000000000000000000? That’s 1 with 18 0’s.
I considered that it could be a formatting issue, so I tried some comparisons:
Var BigNumber As Double = 999999999999999999
Var BiggerNumber As Double = 1000000000000000000
If BigNumber > BiggerNumber Then
Break
ElseIf BigNumber < BiggerNumber Then
Break
Else
Break // This one hits, so they are equal
End If
I’m sure this is some quirk with how they are stored in memory, but I don’t know what it is.
Doubles can have up to 15 or so digits of precision, IIRC.
As the emperor Franz-Josef supposedly said to Mozart: “Well, there it is. Too many digits.”
Ah there it is. Thanks.
Side note: Min and Max functions that support UInt64 would be helpful. That’s how I stumbled upon this.
Doubles are 64 bit floats, it stores values much like humans use in scientific notation, but differently from humans used to d.ddd x 10ⁿ, the computer uses 1.bbb x 2ⁿ.
The IEEE754 format is 1 sign bit, 11 bits for exponent (the n) and 52 bits for the mantissa (the b’s)
The 1.0 (extra fixed 53rd bit) is not stored. It’s a imaginary digit that exists just for calculations and is removed after.
The exponent has a bias of 1023, and it means that what you find there, you should subtract 1023 to get the real value of it.
But let’s focus on the mantissa, the max mantissa (always positive, the sign has its own bit as explained) is:
1111 11111111 11111111 11111111 11111111 11111111 11111111 = 9007199254740991
This 9007199254740991 is the max exact value in digits it can store, and it has 16 decimal digits, but as you can notice, they aren’t all 9’s, so for a max sustainable exact decimal number, we must to give up the 16th digit and consider only the 15 digits that can hold all 9’s.
When doing calculations the floating point math round up the mantissa to fit into those 52 bits, and that’s why a 1.99999999999999999999999 becomes 2.000000000000000 - 1.0 = 1.0 in a mantissa (I’m talking decimal here to make it easily understandable)
3 Likes