簡體   English   中英

如何在 JavaScript 中執行 integer 除法,並分別獲得余數?

[英]How to perform an integer division, and separately get the remainder, in JavaScript?

JavaScript中,我如何獲得:

  1. 給定 integer 進入另一個的總次數?
  2. 其余的?

對於一些數字y和一些除數x計算商 ( quotient ) 和remainder數 ( remaining ) 為:

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% 的效率增益。 還要記住,當a/b<0 && a%b!=0時,它們都與Math.floor不一致。

ES6 引入了新的Math.trunc方法。 這允許修復@MarkElliot 的答案,使其也適用於負數:

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

請注意,與位運算符相比, Math方法的優勢在於它們可以處理超過 2 31的數字。

我通常使用:

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

它可能不是最優雅的,但它確實有效。

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

您可以使用函數parseInt來獲取截斷的結果。

parseInt(a/b)

要獲得余數,請使用 mod 運算符:

a%b

parseInt 對字符串有一些陷阱,以避免使用基數為 10 的基數參數

parseInt("09", 10)

在某些情況下,數字的字符串表示可以是科學計數法,在這種情況下,parseInt 會產生錯誤的結果。

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

此調用將產生 1 作為結果。

Math.floor(operation)返回運算的向下舍入值。

一個問題的例子:

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

第二個問題的例子:

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

JavaScript 按照數學定義計算負數和非整數余數的正確下限。

FLOOR 被定義為“小於參數的最大整數”,因此:

  • 正數:FLOOR(X)=X 的整數部分;
  • 負數:FLOOR(X)=X 的整數部分減 1(因為它必須比參數更小,即更負!)

REMAINDER 被定義為除法的“剩余”(歐幾里得算術)。 當被除數不是整數時,商通常也不是整數,即沒有余數,但是如果商被強制為整數(當有人試圖獲得余數或模數時會發生這種情況浮點數),顯然會有一個非整數“剩余”。

JavaScript 確實會按預期計算所有內容,因此程序員必須小心地提出正確的問題(人們應該小心回答所問的問題!) Yarin 的第一個問題不是“X 與 Y 的整數除法是多少”,而是,相反,“給定整數進入另一個整數的全部次數”。 對於正數,兩者的答案是相同的,但對於負數則不然,因為整數除法(除數除數)將比一個數(除數)“進入”另一個數(除數)的倍小 -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:進入 = -28,余數 = -0.3800000000000079

是的,我注意到了,那里有一個精度問題,但我沒有時間檢查它(我不知道這是 Firefox、Windows 7 還是我的 CPU 的 FPU 的問題)。 不過,對於 Yarin 的問題,它只涉及整數,gammax 的代碼可以完美運行。

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

還有一個關於它的提案Modulus and Additional Integer Math

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]

您可以使用 javascript 中的 Math.floor function 進行運算。 Math.floor 將返回商,% 將返回余數。

const quotient = Math.floor(a/b);
const remainder = a % b;

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

(第一個是商,第二個是余數)

 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

您也可以使用三元來決定如何處理正整數和負整數值。

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

計算頁數可以一步完成: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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM