I want to normalize an array so that each value is
in [0-1)
.. i.e. "the max will never be 1 but the min can be 0."
This is not unlike the random function returning numbers in the same range.
While looking at this, I found that .99999999999999999===1
is true
!
Ditto (1-Number.MIN_VALUE) === 1
But Math.ceil(Number.MIN_VALUE)
is 1
, as it should be.
Some others: Math.floor(.999999999999)
is 0
while Math.floor(.99999999999999999)
is 1
OK so there are rounding problems in JS.
Is there any way I can normalize a set of numbers to lie in the range [0,1)
?
It may help to examine the steps that JavaScript performs of each of your expressions.
In .99999999999999999===1
:
.99999999999999999
is converted to a Number. The closest Number is 1, so that is the result. (The next closest Number is 0.99999999999999988897769753748434595763683319091796875, which is 1–2–53.)In (1-Number.MIN_VALUE) === 1
:
Number.MIN_VALUE
is 2–1074, about 5e–304.In Math.ceil(Number.MIN_VALUE)
:
Number.MIN_VALUE
is 2–1074, about 5e–304.In Math.floor(.999999999999)
:
.999999999999
is converted to a Number. The closest Number is 0.99999999999900002212172012150404043495655059814453125, so that is the result.In Math.floor(.99999999999999999)
:
.99999999999999999
is converted to a Number. The closest Number is 1, so that is the result.There are only two surprising things here, at most. One is that the numerals in the source text are converted to internal Number values. But this should not be surprising. Of course text has to be converted to internal representations of numbers, and the Number type cannot perfectly store all the infinitely many numbers. So it has to round. And of course numbers very near 1 round to 1.
The other possibly surprising thing is that 1-Number.MIN_VALUE
is 1. But this is actually the same issue: The exact result is not representable, but it is very near 1, so 1 is used.
The Math.floor
function works correctly. It never introduces any error, and you do not have to do anything to guarantee that it will round down. It always does.
However, since you want to normalize numbers, it seems likely you are going to divide numbers at some point. When you divide, there may be rounding problems, because many results of division are not exactly representable, so they must be rounded.
However, that is a separate problem, and you have not given enough information in this question to address the specific calculations you plan to do. You should open a separate question for it.