在JavaScript中使用余数进行整数除法?

2020/09/19 06:01 · javascript ·  · 0评论

JavaScript中,如何获取:

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

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

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

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

var num = ~~(a / b);

这对于负数也将正常工作,同时Math.floor()会朝错误的方向四舍五入。

这似乎也是正确的:

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

我在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

ES6引入了新Math.trunc方法。这可以修复@MarkElliot的答案,使其也适用于负数:

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

请注意,Math与按位运算符相比方法的优势在于它们可以处理2 31以上的数字

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

我通常使用:

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

它可能不是最优雅的,但是可以工作。

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

parseInt(a/b)

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

a%b

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

parseInt("09", 10)

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

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

此调用将产生1作为结果。

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

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

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

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

JavaScript确实会按预期计算所有内容,因此程序员必须谨慎地提出适当的问题(人们应谨慎回答所提出的问题!)Yarin的第一个问题不是“ X除以Y的整数除法是什么”,但是,而是“给定整数的整数倍数”。对于正数,两个答案都是相同的,但对于负数,答案是相同的,因为整数除法(除数)将比数字(除数)“乘”另一个(除数)的次数小-1。换句话说,FLOOR将为负数的整数除法返回正确的答案,但是Yarin并没有要求!

gammax正确回答,该代码按照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,余数= -0.3800000000000079

是的,我注意到那里存在精度问题,但是我没有时间检查它(我不知道这是Firefox,Windows 7还是CPU的FPU出现问题)。对于Yarin的问题,尽管它只涉及整数,但gammax的代码运行得很好。

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

第一个问题的示例

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

console.log(z);

安慰:

15

第二个问题的示例

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

console.log(x);

安慰:

4

Alex Moore-Niemi的回答为:

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

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)

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

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

如果数字为正数,则表示一切正常。如果数字为负数,则由于Math.floor处理负数的方式而将其加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
    };
}

如果您需要计算非常大的整数的余数,而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);
}
本文地址:http://javascript.askforanswer.com/zaijavascriptzhongshiyongyushujinxingzhengshuchufa.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!