web-dev-qa-db-ja.com

JavaScriptで余りを持つ整数除算?

JavaScriptでは、どのように取得しますか。

  1. 特定の整数が別の整数になる回数の合計?
  2. 残り?
798
Yarin

いくつかの数yといくつかの除数xでは、商(quotient)と剰余(remainder)を次のように計算します。

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

私はビット演算子の専門家ではありませんが、整数を取得するもう1つの方法があります。

var num = ~~(a / b);

これは負の数に対しても適切に機能しますが、Math.floor()は間違った方向に丸めます。

これも同様に正しいようです。

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

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と矛盾することにも注意してください。

177
KalEl

ES6では新しい Math.trunc メソッドが導入されました。これにより、 @ MarkElliotの回答 を修正して負の数に対しても機能させることができます。

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

Mathメソッドは2を超える数を扱うというビットごとの演算子に勝る利点があります。31

111
Oriol
var remainder = x % y;
return (x - remainder) / y;
23
gammax

切り捨てられた結果を得るために関数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は除算の「残り」として定義されます(ユークリッド算術)。被除数が整数ではない場合、商も通常整数ではありません。つまり、余りはありませんが、商が整数になるように強制されている場合は、 (浮動小数点数)、明らかに、 "整数"の "整数"ではない整数があります。

JavaScriptは期待通りにすべてを計算するので、プログラマーは適切な質問をするように注意しなければなりません(そして人々は質問に答えるように注意するべきです!)代わりに、「特定の整数が別の整数に入る回数」を指定します。正の数の場合、答えは両方の場合で同じですが、負の数ではありません。整数の除算(約数による除算)が、ある数(約数)が別の値(「被除数」)に入る回数より-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、剰余= -0.3800000000000079

確かに、精度の問題があることに気付きましたが、確認する時間がありませんでした(Firefox、Windows 7、またはCPUのFPUのどちらに問題があるのか​​はわかりません)。しかし、Yarinの質問では、整数しか含まないため、gammaxのコードは完全に機能します。

6
Cyberknight

Math.floor(operation)は操作の切り捨てられた値を返します。

1の例st 質問:

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

console.log(z);

コンソール:

15年

例2nd 質問:

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

console.log(x);

コンソール:

4

5
Aetricity

Alex Moore-Niemi の答えとしてのコメント:

divmodを探してここにいるGoogleのRubyistsのために、あなたはそれをそのように実装することができます:

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

結果:

// [2, 33]
2
Alex

私は通常使用します:

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

おそらく最もエレガントではありませんが、うまくいきます。

2
Wolf Elkan

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

(最初は商、2番目は余りです)

1

ページ数の計算は1ステップで実行できます。Math.ceil(x/y)

1
user1920925

3進数を使用して、正および負の整数値の処理方法も決定できます。

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

数が正であれば、すべて問題ありません。負数の場合、Math.floorが負数をどのように処理するかにより、1が加算されます。

0
John Galt

これは常にゼロに向かって切り捨てられます。手遅れかどうかはわかりませんが、ここに行きます。

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

JSランタイムでは表現できないような非常に大きな整数の余りを計算する必要がある場合(2 ^ 32より大きい整数はfloatとして表現されるため、精度が失われます)、いくつかのトリックを行う必要があります。

これは、私たちの日常生活の多くの場合に見られるチェックデジットの多くのケース(銀行口座番号、クレジットカードなど)をチェックするために特に重要です。

まず第一にあなたは文字列としてあなたの数を必要とします(さもなければあなたはすでに正確さを失いましたそして残りは意味をなさない)。

str = '123456789123456789123456789'

文字列を9桁に収めることができるように、残りの部分と文字列の一部を連結できるように、文字列を細かく分割する必要があります。

digits = 9 - String(divisor).length

文字列を分割するための正規表現を用意する

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

たとえば、digitsが7の場合、正規表現は次のようになります。

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

最大長7の空でない部分文字列に一致し、その後ろに7の倍数の文字数が続きます( '(?=...)は正の先読みです)。 。

各部分を整数に変換し、reduce(前の剰余 - または0 - 正の10のべき乗)を足し合わせて剰余を計算します。

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

これは、「減算」剰余アルゴリズムのために機能します。

n mod d = (n - kd) mod d

これは、最後の残りに影響を与えずに、数値の10進表現の「最初の部分」を残りの部分に置き換えることを可能にします。

最終的なコードは次のようになります。

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);
}
0
rewritten