JavaScript에서 나머지로 정수 나누기?
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
위는 각각에 대해 천만 번의 시도를 기반으로합니다.
결론 :(a/b>>0)
(또는 (~~(a/b))
또는 (a/b|0)
)을 사용 하여 약 20 %의 효율성 향상을 달성하십시오. 또한 모두 Math.floor
, when 과 일치하지 않습니다 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;
함수 parseInt
를 사용하여 잘린 결과를 얻을 수 있습니다.
parseInt(a/b)
나머지를 얻으려면 mod 연산자를 사용하십시오.
a%b
parseInt는 밑 수가 10 인 기수 매개 변수를 사용하지 않기 위해 문자열에 몇 가지 함정이 있습니다.
parseInt("09", 10)
어떤 경우에는 숫자의 문자열 표현이 과학적 표기법 일 수 있습니다.이 경우 parseInt는 잘못된 결과를 생성합니다.
parseInt(100000000000000000000000000000000, 10) // 1e+32
이 호출은 결과로 1을 생성합니다.
나는 일반적으로 다음을 사용합니다.
const quotient = (a - a % b) / b;
const remainder = a % b;
아마도 가장 우아하지는 않지만 작동합니다.
JavaScript calculates right the floor of negative numbers and the remainder of non-integer numbers, following the mathematical definitions for them.
FLOOR is defined as "the largest integer number smaller than the parameter", thus:
- positive numbers: FLOOR(X)=integer part of X;
- negative numbers: FLOOR(X)=integer part of X minus 1 (because it must be SMALLER than the parameter, i.e., more negative!)
REMAINDER is defined as the "left over" of a division (Euclidean arithmetic). When the dividend is not an integer, the quotient is usually also not an integer, i.e., there is no remainder, but if the quotient is forced to be an integer (and that's what happens when someone tries to get the remainder or modulus of a floating-point number), there will be a non-integer "left over", obviously.
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 answered correctly, that code works as asked by Yarin. On the other hand, Samuel is wrong, he didn't do the maths, I guess, or he would have seen that it does work (also, he didn't say what was the divisor of his example, but I hope it was 3):
Remainder = X % Y = -100 % 3 = -1
GoesInto = (X - Remainder) / Y = (-100 - -1) / 3 = -99 / 3 = -33
By the way, I tested the code on Firefox 27.0.1, it worked as expected, with positive and negative numbers and also with non-integer values, both for dividend and divisor. Example:
-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079
Yes, I noticed, there is a precision problem there, but I didn't had time to check it (I don't know if it's a problem with Firefox, Windows 7 or with my CPU's FPU). For Yarin's question, though, which only involves integers, the gammax's code works perfectly.
Math.floor(operation)
returns the rounded down value of the operation.
Example of 1st question:
var x = 5;
var y = 10.4;
var z = Math.floor(x + y);
console.log(z);
Console:
15
Example of 2nd question:
var x = 14;
var y = 5;
var z = Math.floor(x%y);
console.log(x);
Console:
4
Alex Moore-Niemi's comment as an answer:
For Rubyists here from Google in search of divmod
, you can implement it as such:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
Result:
// [2, 33]
If you are just dividing with powers of two, you can use bitwise operators:
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];
}
(The first is the quotient, the second the remainder)
Calculating number of pages may be done in one step: Math.ceil(x/y)
You can use ternary to decide how to handle positive and negative integer values as well.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
If the number is a positive, all is fine. If the number is a negative, it will add 1 because of how Math.floor handles negatives.
This will always truncate towards zero. Not sure if it is too late, but here it goes:
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
};
}
If you need to calculate the remainder for very large integers, which the JS runtime cannot represent as such (any integer greater than 2^32 is represented as a float and so it loses precision), you need to do some trick.
This is especially important for checking many case of check digits which are present in many instances of our daily life (bank account numbers, credit cards, ...)
First of all you need your number as a string (otherwise you have already lost precision and the remainder does not make sense).
str = '123456789123456789123456789'
You now need to split your string in smaller parts, small enough so the concatenation of any remainder and a piece of string can fit in 9 digits.
digits = 9 - String(divisor).length
Prepare a regular expression to split the string
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')
For instance, if digits
is 7, the regexp is
/.{1,7}(?=(.{7})+$)/g
It matches a nonempty substring of maximum length 7, which is followed ((?=...)
is a positive lookahead) by a number of characters that is multiple of 7. The 'g' is to make the expression run through all string, not stopping at first match.
Now convert each part to integer, and calculate the remainders by reduce
(adding back the previous remainder - or 0 - multiplied by the correct power of 10):
reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor
This will work because of the "subtraction" remainder algorithm:
n mod d = (n - kd) mod d
which allows to replace any 'initial part' of the decimal representation of a number with its remainder, without affecting the final remainder.
The final code would look like:
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);
}
참고URL : https://stackoverflow.com/questions/4228356/integer-division-with-remainder-in-javascript
'Program Tip' 카테고리의 다른 글
'ref'와 'out'키워드의 차이점은 무엇입니까? (0) | 2020.09.28 |
---|---|
PostgreSQL 사용자 비밀번호를 변경하는 방법은 무엇입니까? (0) | 2020.09.28 |
함수 설계 f (f (n)) == -n (0) | 2020.09.28 |
ThreadLocal 변수는 언제 어떻게 사용해야합니까? (0) | 2020.09.28 |
오류 : vcvarsall.bat를 찾을 수 없습니다. (0) | 2020.09.28 |