Reputation: 2686
According to this post, floating point numbers in JavaScript are not deterministic.
I wonder, is the following code deterministic?
z = Math.floor(x/y)
If not, how can I do deterministic integer division in JavaScript?
Edit: I would like to know if I can rely on the resulting value being the same across different JavaScript implementations (given they follow the standards).
Upvotes: 1
Views: 413
Reputation: 8847
Good question. Short answer: It cannot be assumed to be cross-platform deterministic.
x
and y
can be forced to unsigned 32-bit integers if we apply y = y >>> 0
works. (Other bitwise ops get a signed 32-bit integer.)
However, the moment /
(the division operator) is applied to them, the internal representation of each becomes a floating point number since floating-point division is used under the hood, and needs to take 2 float operands. Then you are stuck with the same problem: For the right pairs of numbers, rounding still comes into play (see this question). Which, as Scott correctly stated, is where the actual platform non-determinism comes in.
Perhaps if you can assure small enough values of the dividend, you may be fine. I wouldn't risk it.
To assure that you are working only with 32-bit integers throughout, you will have to implement integer division using bitwise logic, see this question & answer. That is one tedious but surefire way to solve the problem.
Upvotes: 0
Reputation: 50787
It should be deterministic.
According to the specification
20.2.2.16 Math.floor ( x )
Returns the greatest (closest to +∞) Number value that is not greater than x and is equal to a mathematical integer. If x is already an integer, the result is x.
- If x is NaN, the result is NaN.
- If x is +0, the result is +0.
- If x is −0, the result is −0.
- If x is +∞, the result is +∞.
- If x is −∞, the result is −∞.
- If x is greater than 0 but less than 1, the result is +0.
NOTE The value of Math.floor(x) is the same as the value of -Math.ceil(-x).
The non-determinism of some Math functions has to do with possible rounding issues when the underlying engine uses higher-precision numbers. That shouldn't be a factor here.
Update :
Division is also deterministic. Here the JS specification depends on the IEEE 754 specification. But that specification is deterministic. (Sorry no link, as the actual specification is paywalled.)
The non-determinisim is in the less common JS functions.
Upvotes: 0
Reputation: 745
Yes. Math.floor always returns a lowest integer value.
Whereas this is not deterministic:
z = 3/1.5; //z !== 2
This, by the function's design, is:
z = Math.floor(3/1.5); //z === 2
See the MDN docs for more details.
Upvotes: -2