JavaScript % (modulo) gives a negative result for negative numbers

前端 未结 11 1344
死守一世寂寞
死守一世寂寞 2020-11-22 11:01

According to Google Calculator (-13) % 64 is 51.

According to Javascript (see this JSBin) it is -13.

How do I fix this

相关标签:
11条回答
  • 2020-11-22 12:03

    Using Number.prototype is SLOW, because each time you use the prototype method your number is wrapped in an Object. Instead of this:

    Number.prototype.mod = function(n) {
      return ((this % n) + n) % n;
    }
    

    Use:

    function mod(n, m) {
      return ((n % m) + m) % m;
    }
    

    See: http://jsperf.com/negative-modulo/2

    ~97% faster than using prototype. If performance is of importance to you of course..

    0 讨论(0)
  • 2020-11-22 12:04

    A "mod" function to return a positive result.

    var mod = function (n, m) {
        var remain = n % m;
        return Math.floor(remain >= 0 ? remain : remain + m);
    };
    mod(5,22)   // 5
    mod(25,22)  // 3
    mod(-1,22)  // 21
    mod(-2,22)  // 20
    mod(0,22)   // 0
    mod(-1,22)  // 21
    mod(-21,22) // 1
    

    And of course

    mod(-13,64) // 51
    
    0 讨论(0)
  • 2020-11-22 12:07

    The accepted answer makes me a little nervous because it re-uses the % operator. What if Javascript changes the behavior in the future?

    Here is a workaround that does not re-use %:

    function mod(a, n) {
        return a - (n * Math.floor(a/n));
    }
    
    mod(1,64); // 1
    mod(63,64); // 63
    mod(64,64); // 0
    mod(65,64); // 1
    mod(0,64); // 0
    mod(-1,64); // 63
    mod(-13,64); // 51
    mod(-63,64); // 1
    mod(-64,64); // 0
    mod(-65,64); // 63
    
    0 讨论(0)
  • 2020-11-22 12:07

    This is not a bug, there's 3 functions to calculate modulo, you can use the one which fit your needs (I would recommend to use Euclidean function)

    Truncating the decimal part function

    console.log(  41 %  7 ); //  6
    console.log( -41 %  7 ); // -6
    console.log( -41 % -7 ); // -6
    console.log(  41 % -7 ); //  6
    

    Integer part function

    Number.prototype.mod = function(n) {
        return ((this%n)+n)%n;
    };
    
    console.log( parseInt( 41).mod( 7) ); //  6
    console.log( parseInt(-41).mod( 7) ); //  1
    console.log( parseInt(-41).mod(-7) ); // -6
    console.log( parseInt( 41).mod(-7) ); // -1
    

    Euclidean function

    Number.prototype.mod = function(n) {
        var m = ((this%n)+n)%n;
        return m < 0 ? m + Math.abs(n) : m;
    };
    
    console.log( parseInt( 41).mod( 7) ); // 6
    console.log( parseInt(-41).mod( 7) ); // 1
    console.log( parseInt(-41).mod(-7) ); // 1
    console.log( parseInt( 41).mod(-7) ); // 6
    
    0 讨论(0)
  • 2020-11-22 12:08

    The % operator in JavaScript is the remainder operator, not the modulo operator (the main difference being in how negative numbers are treated):

    -1 % 8 // -1, not 7

    0 讨论(0)
提交回复
热议问题