JavaScript % (모듈로)는 음수에 대해 음수 결과를 제공합니다.
구글 계산기 에 따르면 (-13) % 64
입니다 51
.
자바 스크립트에 따르면 (이 참조 JSBin을 그것이) -13
.
이 문제를 어떻게 해결합니까?
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
이 기사에서 가져온 : JavaScript Modulo Bug
Number.prototype
프로토 타입 방법을 사용할 때마다 숫자가로 래핑되므로 Using 는 SLOW Object
입니다. 이 대신에 :
Number.prototype.mod = function(n) {
return ((this % n) + n) % n;
}
사용하다:
function mod(n, m) {
return ((n % m) + m) % m;
}
참조 : http://jsperf.com/negative-modulo/2
프로토 타입을 사용하는 것보다 ~ 97 % 빠릅니다. 물론 성능이 중요하다면 ..
%
JavaScript 의 연산자는 모듈로 연산자가 아닌 나머지 연산자입니다 (주요 차이점은 음수가 처리되는 방식에 있음).
-1 % 8 // -1, not 7
긍정적 인 결과를 반환하는 "mod"함수
var mod = function (n, m) {
var remain = n % m;
return Math.floor(remain >= 0 ? remain : remain + m);
};
mod(5,22) // 5
mod(25,22) // 3
mod(-1,22) // 21
mod(-2,22) // 20
mod(0,22) // 0
mod(-1,22) // 21
mod(-21,22) // 1
그리고 물론
mod(-13,64) // 51
허용 된 답변은 % 연산자를 재사용하기 때문에 약간 긴장합니다. Javascript가 나중에 동작을 변경하면 어떻게됩니까?
다음은 %를 재사용하지 않는 해결 방법입니다.
function mod(a, n) {
return a - (n * Math.floor(a/n));
}
mod(1,64); // 1
mod(63,64); // 63
mod(64,64); // 0
mod(65,64); // 1
mod(0,64); // 0
mod(-1,64); // 63
mod(-13,64); // 51
mod(-63,64); // 1
mod(-64,64); // 0
mod(-65,64); // 63
자바 스크립트 모듈로 연산
과학적 계산 또는 알고리즘의 성공적인 구현은 특정 언어 또는 프레임 워크가 제공하는 기능을 이해하고 제한을 이해함으로써 가능합니다.
컴퓨터는 정밀한 과학 도구이지만 개별 공간에서 엔티티를 조작하여 작동합니다 (화면에 제한된 수의 픽셀이 있고 각 수의 뒤에 제한된 수의 비트가 있습니다).
제한 사항이나 프레임 워크 사양을 무시하고 곧 수학 공식과 작성하려는 코드 사이에 임피던스 불일치가 있음을 알게 될 것입니다.
모듈로 연산자
때때로 틀린 광고 또는 이해 된 프레임 워크 기능이나 연산자로 인해 상황이 복잡 해지는 경우가 있습니다. 이 기사는 모듈로 연산자에 중점을 둡니다.
C # 또는 JavaScript 프로그래머에게 해당 언어의 모듈로 연산자가 무엇인지 물어보십시오. % (예 : 백분율 기호)로 응답 할 가능성이 큽니다. 많은 문서는 모듈러스 연산자로 % 기호를 나타냅니다.
와! 이것은 미묘하지만 매우 위험한 실수입니다. C # 및 JavaScript에서 % 연산자는 실제로 한 피연산자가 두 번째 피연산자로 나뉘어 질 때 남은 나머지 (기호 포함)를 계산하는 데 사용됩니다. 따라서 피연산자는 부호있는 나머지 연산자로 올바르게 참조해야합니다.
첫눈에 부호있는 나머지 연산자는 모듈로 연산자와 유사하게 작동합니다. JavaScript에서 반환 된 결과와 Google에서 반환 된 결과를 비교하여 몇 가지 테스트를 수행해 보겠습니다.
Chrome에서 콘솔을 엽니 다 (F12를 누르고 콘솔 탭을 선택). 왼쪽 열의 계산을 하나씩 입력하십시오. 그런 다음 Google 검색 창에 동일한 표현식을 입력하십시오. 결과를 확인하십시오. 그들은 같아야합니다.
JavaScript Google
5 % 3 2 2
26 % 26 0 0
15 % 12 3 3
이제 첫 번째 피연산자로 음수 값을 사용하려고합니다.
놀라다!
-5 % 3 = 1 (Google에 따름) -5 % 3 = -2 (JavaScript에 따름)
글쎄 ... JavaScript에서 % 연산자의 정의 (또는 C # 또는 다른 많은 언어)를 보면 실제로 놀라운 일이 아닙니다. Google은 실제 모듈로를 계산하지만 이러한 컴퓨터 언어는 서명 된 알림을 계산합니다.
그러나 모든 프로그래밍 언어 / 프레임 워크가 %에 대해 동일한 구현을 갖는 것은 아닙니다. 예를 들어 Python에서 % 연산자는 Google과 같은 방식으로 실제 모듈로를 계산합니다.
언어 간의 동작 차이로 인해 계산에 미묘한 오류가 발생할 수 있습니다. 특히 한 언어에서 다른 언어로 알고리즘을 이식하려는 경우 더욱 그렇습니다!
이해되는 문제는 반으로 해결 된 문제입니다.
모듈로 산술을 사용하여 JavaScript로 (과학적인) 계산을 구현해야한다고 가정 해 봅시다.
JavaScript에는 실제 모듈로 연산자가 없다는 것을 이해 했으므로 모듈로 연산을 함수로 쉽게 구현할 수 있습니다.
JavaScript에서 모듈로를 구현하는 방법에는 여러 가지가 있습니다. 3 가지 방법을 보여 드리겠습니다.
// Implement modulo by replacing the negative operand
// with an equivalent positive operand that has the same wrap-around effect
function mod(n, p)
{
if ( n < 0 )
n = p - Math.abs(n) % p;
return n % p;
}
// Implement modulo by relying on the fact that the negative remainder
// is always p numbers away from a positive reminder
// Ex: -5 % 3 | -5 = -2 * 3 + 1 and -5 = -1 * 3 + (-2) | -2 + 3 = 1
function mod(n, p)
{
var r = n % p;
return r < 0 ? r + p : r;
}
// Implement modulo by solving n = v * p + r equation
function mod(n, p)
{
return n - p * Math.floor( n / p );
}
보다 정확한 도구를 사용하여 이제 (과학적인) 계산을 수행 할 수 있으며 매번 정확한 결과를 얻을 수 있습니다.
참고 : 모듈로 산술을 사용하는 많은 계산이 있습니다… Caesar Cipher / ROT13 코드를 구현할 때 이러한 새로운 모듈로 함수를 사용하는 방법을 보려면이 기사를 확인 하십시오 .
예상대로 동작하지 않지만 JavaScript가 '동작'이 아님을 의미하지는 않습니다. 모듈로 계산을 위해 만들어진 JavaScript입니다. 정의에 따라 두 가지 대답 모두 의미가 있기 때문입니다.
Wikipedia에서 이것을 보십시오 . 다양한 언어가 결과의 부호를 어떻게 선택했는지 오른쪽에서 볼 수 있습니다.
경우 x
정수이며 n
2의 힘, 당신은 사용할 수 있습니다 x & (n - 1)
대신 x % n
.
> -13 & (64 - 1)
51
따라서 정도를 조정하려고하면 (-50도-200 도인 경우) 다음과 같은 것을 사용하는 것이 좋습니다.
function modrad(m) {
return ((((180+m) % 360) + 360) % 360)-180;
}
나는 음수 a와 음수 n도 처리합니다.
//best perf, hard to read
function modul3(a,n){
r = a/n | 0 ;
if(a < 0){
r += n < 0 ? 1 : -1
}
return a - n * r
}
// shorter code
function modul(a,n){
return a%n + (a < 0 && Math.abs(n));
}
//beetween perf and small code
function modul(a,n){
return a - n * Math[n > 0 ? 'floor' : 'ceil'](a/n);
}
이것은 버그가 아니며 모듈로를 계산하는 3 가지 함수가 있습니다. 필요에 맞는 것을 사용할 수 있습니다 (유클리드 함수를 사용하는 것이 좋습니다)
소수 부분 기능 자르기
console.log( 41 % 7 ); // 6
console.log( -41 % 7 ); // -6
console.log( -41 % -7 ); // -6
console.log( 41 % -7 ); // 6
정수 부분 함수
Number.prototype.mod = function(n) {
return ((this%n)+n)%n;
};
console.log( parseInt( 41).mod( 7) ); // 6
console.log( parseInt(-41).mod( 7) ); // 1
console.log( parseInt(-41).mod(-7) ); // -6
console.log( parseInt( 41).mod(-7) ); // -1
유클리드 기능
Number.prototype.mod = function(n) {
var m = ((this%n)+n)%n;
return m < 0 ? m + Math.abs(n) : m;
};
console.log( parseInt( 41).mod( 7) ); // 6
console.log( parseInt(-41).mod( 7) ); // 1
console.log( parseInt(-41).mod(-7) ); // 1
console.log( parseInt( 41).mod(-7) ); // 6
당신을 위해 일할 NPM 패키지가 있습니다. 다음 명령으로 설치할 수 있습니다.
npm install just-modulo --save
README에서 복사 한 사용법
import modulo from 'just-modulo';
modulo(7, 5); // 2
modulo(17, 23); // 17
modulo(16.2, 3.8); // 17
modulo(5.8, 3.4); //2.4
modulo(4, 0); // 4
modulo(-7, 5); // 3
modulo(-2, 15); // 13
modulo(-5.8, 3.4); // 1
modulo(12, -1); // NaN
modulo(-3, -8); // NaN
modulo(12, 'apple'); // NaN
modulo('bee', 9); // NaN
modulo(null, undefined); // NaN
GitHub 리포지토리는 다음 링크를 통해 찾을 수 있습니다.
https://github.com/angus-c/just/tree/master/packages/number-modulo
'IT story' 카테고리의 다른 글
C에서 함수 포인터의 typedef 이해 (0) | 2020.04.23 |
---|---|
안드로이드 앱에서 인터넷 연결을 확인하기위한 방송 수신기 (0) | 2020.04.23 |
Assert.Throws를 사용하여 예외 유형을 지정하려면 어떻게합니까? (0) | 2020.04.23 |
Html.ActionLink를 사용하여 다른 컨트롤러에서 작업 호출 (0) | 2020.04.23 |
ANTLR : 간단한 예가 있습니까? (0) | 2020.04.23 |