如何在JavaScript中执行整数除法并分别获得余数?

javascript中,我如何获得:

  1. 一个给定的整数进入另一个整数的总次数?
  2. 其余的?
1059037 次浏览

对于一些数字y和一些除数x,计算商(quotient[1]和余数(remainder)为:

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

示例:

const quotient = Math.floor(13/3); // => 4 => the times 3 fits into 13const remainder = 13 % 3;          // => 1

[1]整数由一个数除以另一个数而产生的整数

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

var num = ~~(a / b);

这也将适用于负数,而Math.floor()将在错误的方向上舍入。

这似乎也是正确的:

var num = (a / b) >> 0;
var remainder = x % y;return (x - remainder) / y;

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

-100/3             // -33.33..., 0.3663 millisecMath.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 millisecMath.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%的效率增益。还要记住,当a/b<0 && a%b!=0时,它们都与Math.floor不一致。

JavaScript根据它们的数学定义正确计算负数和非整数的余数。

FLOOR定义为“小于参数的最大整数”,因此:

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

REMAINDER被定义为除法(欧几里德算术)的“剩余”。当股息不是整数时,商通常也不是整数,即没有余数,但是如果商被迫成为整数(当有人试图获得浮点数的余数或模时会发生这种情况),显然会有一个非整数“剩余”。

JavaScript确实按预期计算了所有内容,所以程序员必须小心问适当的问题(人们应该小心回答所问的问题!)Yarin的第一个问题不是“什么是X除以Y的整数”,而是“给定整数的整个次数进入另一个整数”。对于正数,答案对两者都是一样的,但对负数不是,因为整数除法(除数除数)将比一个数字(除数)“进入”另一个数字(除数)的次数小-1。换句话说,FLOOR会返回负数整数除法的正确答案,但Yarin没有问这个!

另一方面,Samuel错了,我猜他没有做数学,或者他会看到它确实有效(此外,他没有说他的例子的除数是什么,但我希望是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的代码运行完美。

ES6引入了新的#0方法。这允许修复@MarkElliot的回答以使其也适用于负数:

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

请注意,Math方法比按位运算符具有优势,它们可以处理超过231的数字。

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

1st问题示例:

const x = 5;const y = 10.4;const z = Math.floor(x + y);
console.log(z);

2nd问题示例:

const x = 14;const y = 5;const z = Math.floor(x % y);
console.log(x);

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

parseInt(a/b)

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

a%b

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

parseInt("09", 10)

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

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

此调用将产生1结果。

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

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

如果数字是正数,一切都好。如果数字是负数,它会加1,因为Math.floor如何处理负数。

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

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};}

我通常使用:

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

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

亚历克斯·摩尔-涅米的评论作为答案:

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

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

结果:

// [2, 33]

如果你只是用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];}

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

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

如果您需要计算非常大的整数的余数,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);}

(就我个人而言,我不会这样做,但认为这是一个有趣的方式来做一个例子)上面提到的方法肯定是更好,因为这调用了多个函数,因此速度较慢,并且占用了更多的空间。

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);

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

还有一个建议正在进行中模和附加整数数学

 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 valueconsole.log(divide.division)     //to get Floating division of two valueconsole.log(divide.Remainder)     //to get Remainder of two valueconsole.log(divide.calculate())   //to get object containing all the values