Modulo Operator %%

peter miller fuchsia.groan at virgin.net
Fri Aug 16 15:50:40 UTC 2019


Hi,

+1 for _at_least_ having `Math.mod()`

And here's a reason why:

The code `mod = (x,y) => ( ( x % y ) + y ) % y` is not only slow but  
inaccurate. For example, for `mod( -249825144445569.97,  
-2022673516699079.8)` gives `-249825144445569.75` (Chrome Version  
77.0.3865.35) instead of `-249825144445569.97`

I then switched to `mod = (x,y) => x - Math.floor( x / y ) * y` which  
gives an accurate answer, and is faster.

But, on a hunch that flow control would be faster than arithmetic, I  
devised this:

```
mod = (x,y) => {
   const z = x % y;
   return  (y >= 0 && z >= 0 ) || ( y < 0 && z <= 0 ) ? z : y + z;
}
```
And that is _sometimes_ the fastest approach -- assuming I haven't screwed  
up the maths; cf  https://jsbench.me/lrjze7oqv9/2 Although it does seem to  
depend on the numbers - with the `Math.floor()` approach sometimes coming  
out faster.

And this all neglects BigInts, Infinites, NaNs, and signed zeroes.

So this isn't a trivial function to polyfill. And, for that reason alone,  
it should be in the standard. (And if we get it in Math, and convince  
people to use it, then the pressure for a more ergonomic solution will  
increase.)

Peter


More information about the es-discuss mailing list