整数除以JavaScript中的余数?

时间:2010-11-19 18:53:14

标签: javascript math modulo integer-division

在JavaScript中,我该如何获得:

  1. 给定整数进入另一个整数的整数次?
  2. 剩下的?

19 个答案:

答案 0 :(得分:1057)

对于某些数字y而某些除数x计算商(quotient)和余数(remainder)为:

var quotient = Math.floor(y/x);
var remainder = y % x;

答案 1 :(得分:339)

我不是按位运算符的专家,但这是另一种获取整数的方法:

var num = ~~(a / b);

这也适用于负数,而Math.floor()将朝错误的方向进行。

这似乎也是正确的:

var num = (a / b) >> 0;

答案 2 :(得分:178)

我在Firefox上进行了一些速度测试。

-100/3             // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34,       0.5016 millisec
~~(-100/3)         // -33,       0.3619 millisec
(-100/3>>0)        // -33,       0.3632 millisec
(-100/3|0)         // -33,       0.3856 millisec
(-100-(-100%3))/3  // -33,       0.3591 millisec

/* a=-100, b=3 */
a/b                // -33.33..., 0.4863 millisec
Math.floor(a/b)    // -34,       0.6019 millisec
~~(a/b)            // -33,       0.5148 millisec
(a/b>>0)           // -33,       0.5048 millisec
(a/b|0)            // -33,       0.5078 millisec
(a-(a%b))/b        // -33,       0.6649 millisec

上述内容基于每项1000万次试验。

结论:使用(a/b>>0)(或(~~(a/b))(a/b|0))可将效率提高约20%。另请注意,Math.floor时,它们与a/b<0 && a%b!=0不一致。

答案 3 :(得分:112)

ES6引入了新的Math.trunc方法。这样可以修复@MarkElliot's answer以使其适用于负数:

var div = Math.trunc(y/x);
var rem = y % x;

请注意,Math方法优于按位运算符,它们可以处理超过2 31 的数字。

答案 4 :(得分:24)

var remainder = x % y;
return (x - remainder) / y;

答案 5 :(得分:13)

您可以使用函数parseInt来获得截断结果。

parseInt(a/b)

要获得余数,请使用mod运算符:

a%b

parseInt对字符串有一些缺陷,以避免使用基数为10的基数参数

parseInt("09", 10)

在某些情况下,数字的字符串表示形式可以是科学记数法,在这种情况下,parseInt将产生错误的结果。

parseInt(100000000000000000000000000000000, 10) // 1e+32

此调用将产生1。

答案 6 :(得分:6)

JavaScript根据它们的数学定义计算负数的底限和非整数的其余部分。

FLOOR定义为&#34;小于参数&#34;的最大整数,因此:

  • 正数:FLOOR(X)= X的整数部分;
  • 负数:FLOOR(X)= X的整数部分减去1(因为它必须比参数小,即更负!)

REMAINDER被定义为&#34;遗留下来&#34;分裂(欧几里德算术)。当被除数不是整数时,商通常也不是整数,即没有余数,但如果商被强制为整数(并且当有人试图得到余数时会发生什么)或浮点数的模数),显然会有一个非整数&#34;剩下#34;

JavaScript会按预期计算所有内容,因此程序员必须小心提出正确的问题(人们应该小心回答所问的内容!)Yarin的第一个问题不是&#34;什么是X由Y&#34;整数除以,而是,#34;给定整数进入另一个&#34;的整数倍。对于正数,答案对于两者都是相同的,但对于负数则不是,因为整数除法(除数除以)将比数字(除数)&#34;进入&#34;的时间小-1。另一个(股息)。换句话说,FLOOR会返回一个负数整数除法的正确答案,但是Yarin没有问过这个问题!

gammax回答正确,该代码按Yarin的要求运行。另一方面,塞缪尔是错的,我猜他没有做数学,或者他会看到它确实有效(同样,他也没有说出他的例子的除数是什么,但是我希望它是3):

剩余= X%Y = -100%3 = -1

GoesInto =(X - 余数)/ Y =( - 100 - -1)/ 3 = -99 / 3 = -33

顺便说一下,我测试了Firefox 27.0.1上的代码,它按预期工作,有正数和负数,也有非整数值,分别用于分红和除数。例如:

-100.34 / 3.57:GoesInto = -28,Remainder = -0.3800000000000079

是的,我注意到,那里存在精确问题,但我没有时间检查它(我不知道它是否是Firefox,Windows 7或我的问题) CPU的FPU)。但是,对于Yarin的问题,只涉及整数,gammax的代码完美无缺。

答案 7 :(得分:5)

Math.floor(operation)返回操作的向下舍入值。

1 st 问题的例子:

var x = 5;
var y = 10.4;
var z = Math.floor(x + y);

console.log(z);

控制台:

  

15

2 nd 问题的例子:

var x = 14;
var y = 5;
var z = Math.floor(x%y);

console.log(x);

控制台:

  

4

答案 8 :(得分:2)

我通常使用:

const quotient =  (a - a % b) / b;
const remainder = a % b;

它可能不是最优雅的,但它有效。

答案 9 :(得分:2)

Alex Moore-Niemi的评论作为答案:

对于Google搜索divmod的Rubyists,您可以这样实现:

function divmod(x, y) {
  var div = Math.trunc(x/y);
  var rem = x % y;
  return [div, rem];
}

结果:

// [2, 33]

答案 10 :(得分:1)

如果你只是用2的幂除法,你可以使用按位运算符:

export function divideBy2(num) {
  return [num >> 1, num & 1];
}

export function divideBy4(num) {
  return [num >> 2, num & 3];
}

export function divideBy8(num) {
  return [num >> 3, num & 7];
}

(第一个是商,第二个是余数)

答案 11 :(得分:1)

计算页数可以一步完成: Math.ceil(X / Y)

答案 12 :(得分:0)

 function integerDivison(dividend, divisor){
    
        this.Division  = dividend/divisor;
        this.Quotient = Math.floor(dividend/divisor);
         this.Remainder = dividend%divisor;
        this.calculate = ()=>{
            return {Value:this.Division,Quotient:this.Quotient,Remainder:this.Remainder};
        }
         
    }

  var divide = new integerDivison(5,2);
  console.log(divide.Quotient)      //to get Quotient of two value 
  console.log(divide.division)     //to get Floating division of two value 
  console.log(divide.Remainder)     //to get Remainder of two value 
  console.log(divide.calculate())   //to get object containing all the values

答案 13 :(得分:0)

const idivmod = (a, b) => [a/b |0, a%b];

还有一项提案正在研究中 Modulus and Additional Integer Math

答案 14 :(得分:0)

这是一种执行此操作的方法。 (我个人不会那样做,但是认为这是一个有趣的例子)

function intDivide(numerator, denominator) {
  return parseInt((numerator/denominator).toString().split(".")[0]);
}

let x = intDivide(4,5);
let y = intDivide(5,5);
let z = intDivide(6,5);
console.log(x);
console.log(y);
console.log(z);

答案 15 :(得分:0)

为什么不这样呢?

var quotient = ((y - (y % x)) / x);
var remainder = (y % x);

答案 16 :(得分:0)

如果需要计算非常大的整数的余数,而JS运行时则不能这样表示(任何大于2 ^ 32的整数都表示为浮点数,因此会失去精度),则需要做一些技巧。

这对于检查日常生活中很多情况下出现的许多支票号码(银行帐号,信用卡等)尤其重要

首先,您需要将数字作为字符串(否则,您已经失去了精度,而其余部分则没有意义)。

str = '123456789123456789123456789'

您现在需要将字符串分成较小的部分,该部分应足够小,以便将其余部分和一段字符串串联起来可以容纳9位数字。

digits = 9 - String(divisor).length

准备正则表达式以分割字符串

splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')

例如,如果digits为7,则正则表达式为

/.{1,7}(?=(.{7})+$)/g

它匹配最大长度为7的非空子字符串,其后跟((?=...)是正向超前)是多个7的倍数的字符。“ g”是使表达式在所有字符串,不会在第一次比赛时停止。

现在将每个部分转换为整数,并用reduce计算余数(将前一个余数-或0-乘以10的正确幂):

reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor

由于“减法”余数算法,这将起作用:

n mod d = (n - kd) mod d

允许将数字的十进制表示形式的任何“初始部分”替换为其剩余部分,而不会影响最终的剩余部分。

最终代码如下:

function remainder(num, div) {
  const digits = 9 - String(div).length;
  const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
  const mult = Math.pow(10, digits);
  const reducer = (rem, piece) => (rem * mult + piece) % div;

  return str.match(splitter).map(Number).reduce(reducer, 0);
}

答案 17 :(得分:0)

这将始终截断为零。 不确定是否为时已晚,但在这里:

function intdiv(dividend, divisor) { 
    divisor = divisor - divisor % 1;
    if (divisor == 0) throw new Error("division by zero");
    dividend = dividend - dividend % 1;
    var rem = dividend % divisor;
    return { 
        remainder: rem, 
        quotient: (dividend - rem) / divisor
    };
}

答案 18 :(得分:0)

您也可以使用三元来决定如何处理正整数和负整数值。

var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1

如果数字是正数,一切都很好。如果数字为负数,则会因为Math.floor处理负数而添加1。