Simon Farshid
Simon Farshid

Reputation: 2686

Is Math.floor(x/y) cross-platform deterministic?

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

Answers (3)

Engineer
Engineer

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

Scott Sauyet
Scott Sauyet

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

Byron Jones
Byron Jones

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

Related Questions