JavaScript %(modulo)는 음수에 대해 음의 결과를 제공합니다.
Google Calculator에 따르면 (-13) % 64
이51
.
Javascript(이 JSBin 참조)에 따르면-13
.
이거 어떻게 고쳐야 돼요?
Number.prototype.mod = function (n) {
"use strict";
return ((this % n) + n) % n;
};
이 글에서 인용한 내용:JavaScript Modulo 버그
사용.Number.prototype
시제품 방법을 사용할 때마다 번호가 로 둘러싸여 있기 때문에 느립니다.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의 연산자는 modulo 연산자가 아닌 나머지 연산자입니다(음수 처리 방법에 대한 주요 차이점).
-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
한다면x
정수입니다.n
2의 거듭제곱입니다.x & (n - 1)
대신x % n
.
> -13 & (64 - 1)
51
예상대로 동작하지 않지만 자바스크립트가 동작하지 않는 것은 아닙니다.모듈로 계산을 위해 만들어진 JavaScript입니다.왜냐하면, 정의상 어느 하나의 답이 말이 되기 때문입니다.
Wikipedia에서 확인하세요.다른 언어들이 결과의 부호를 어떻게 선택했는지 오른쪽에서 볼 수 있습니다.
음수 모듈로 수정(리마인더 연산자)%
)
ES6 Arrow 기능을 사용하여 번호 프로토타입을 위험하게 확장하지 않고 단순화
const mod = (n, m) => (n % m + m) % m;
console.log(mod(-90, 360)); // 270 (Instead of -90)
이것은 버그가 아니고, 모듈로를 계산하는 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
따라서 (-50도 -200도일 경우) 도수를 조정하려고 하면 다음과 같은 방법을 사용할 수 있습니다.
function modrad(m) {
return ((((180+m) % 360) + 360) % 360)-180;
}
나도 negative a와 negative 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);
}
당신에게 도움이 될 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
예를 들어, 0이 아닌 범위의 최소값을 지정할 수 있다는 점을 제외하고 모듈로처럼 정렬하는 "랩" 함수가 있습니다.
const wrap = (value = 0, min = 0, max = 10) =>
((((value - min) % (max - min)) + (max - min)) % (max - min)) + min;
기본적으로는 진정한 모듈로 공식을 취해서 상쇄해서min
, 「0」을 추가합니다.min
이치노
두 값 사이에서 유지할 값이 있는 경우 유용합니다.
언급URL : https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
'source' 카테고리의 다른 글
MariaDB/MySQL 복합 고유 인덱스가 유효하지 않습니다. (0) | 2022.09.25 |
---|---|
타입에 따라 포인터의 사이즈가 다른 플랫폼이 있나요? (1) | 2022.09.25 |
MySQL 쿼리에서 타임스탬프를 현재 날짜로 변환 (0) | 2022.09.25 |
WordPress를 사용하여 URL에서 추가 변수를 전달하는 방법 (1) | 2022.09.25 |
PHP에서 폐쇄란 무엇이며 왜 "사용" 식별자를 사용하는가? (0) | 2022.09.25 |