在JavaScript中,我如何得到:

一个给定整数除另一个整数的整数倍是多少? 其余的呢?


对于某个数y和某个除数x,计算商(商)[1]和余数(余)为:

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

例子:

const quotient = Math.floor(13/3); // => 4 => the times 3 fits into 13  
const 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 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%左右的效率提升。还要记住,它们都与数学不一致。地板,当a/b<0 && a%b!=0。


JavaScript根据负数的数学定义计算负数的底数和非整数的余数。

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

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

余数被定义为除法(欧几里得算术)的“剩余部分”。当被除数不是整数时,商通常也不是整数,即没有余数,但如果商被强制为整数(这就是当有人试图得到一个浮点数的余数或模量时发生的情况),显然会有一个非整数“剩下”。

JavaScript does calculate everything as expected, so the programmer must be careful to ask the proper questions (and people should be careful to answer what is asked!) Yarin's first question was NOT "what is the integer division of X by Y", but, instead, "the WHOLE number of times a given integer GOES INTO another". For positive numbers, the answer is the same for both, but not for negative numbers, because the integer division (dividend by divisor) will be -1 smaller than the times a number (divisor) "goes into" another (dividend). In other words, FLOOR will return the correct answer for an integer division of a negative number, but Yarin didn't ask that!

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,余数 = -0.38000000000000079

是的,我注意到,这里有一个精度问题,但我没有时间检查它(我不知道这是否是Firefox, Windows 7或我的CPU的FPU的问题)。然而,对于Yarin的问题,它只涉及整数,gammax的代码完美地工作。


ES6引入了新的数学。trunc方法。这允许修复@MarkElliot的答案,使其适用于负数:

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

注意,Math方法与位运算符相比有一个优势,那就是它们处理大于231的数字。


floor(operation)返回操作的四舍五入值。

第一个问题的例子:

Const x = 5; Const y = 10.4; const z =数学。地板(x + y); console.log (z);

第二个问题的例子:

Const x = 14; Const y = 5; const z =数学。地板(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,因为数学。地板处理否定。


它总是截断为零。 不知道是不是太迟了,但我要说的是:

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;

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


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

对于从谷歌搜索divmod的ruby,你可以这样实现它:

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,则regexp为

/.{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);
}

这里有一个方法。(就个人而言,我不会这样做,但认为这是一个有趣的方式来做的例子)上面提到的方式肯定是更好的,因为它调用多个函数,因此更慢,以及占用更多的空间在你的包。

函数intDivide(分子,分母){ 回归方法((分子/分母).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 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