JavaScriptで、どのように取得しますか:
- 与えられた整数が別の整数に入る回数全体?
- 残り?
いくつかの数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
上記は、それぞれの1,000万回の試行に基づいています。
結論:((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;
メソッドには、2 31Math
を超える数値で機能するという、ビット演算子よりも優れていることに注意してください。
私は通常使用します:
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)
操作の切り捨てられた値を返します。
最初の質問の例:
var x = 5;
var y = 10.4;
var z = Math.floor(x + y);
console.log(z);
コンソール:
15
2番目の質問の例:
var x = 14;
var y = 5;
var z = Math.floor(x%y);
console.log(x);
コンソール:
4
JavaScriptは、負の数のフロアと非整数の余りを、それらの数学的定義に従って正しく計算します。
FLOORは、「パラメーターよりも小さい最大の整数」として定義されます。したがって、次のようになります。
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:GoesInto = -28、Remainder = -0.3800000000000079
はい、そこに精度の問題があることに気づきましたが、それをチェックする時間がありませんでした(Firefox、Windows 7、またはCPUのFPUに問題があるかどうかはわかりません)。ただし、Yarinの質問では、整数のみが関係しているため、gammaxのコードは完全に機能します。
const idivmod = (a, b) => [a/b |0, a%b];
それに取り組んでいる提案もあります モジュラスと追加の整数数学
答えとしてのAlexMoore-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];
}
(最初は商、2番目は余りです)
ページ数の計算は1つのステップで実行できます:Math.ceil(x / y)
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
3進数を使用して、正と負の整数値の処理方法を決定することもできます。
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の場合、正規表現は
/.{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
これにより、数値の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);
}
これを行う方法は次のとおりです。(個人的にはこの方法では行いませんが、例としては楽しい方法だと思いました)
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);