source

JavaScript %(modulo)는 음수에 대해 음의 결과를 제공합니다.

gigabyte 2022. 9. 25. 21:20
반응형

JavaScript %(modulo)는 음수에 대해 음의 결과를 제공합니다.

Google Calculator에 따르면 (-13) % 6451.

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정수입니다.n2의 거듭제곱입니다.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

반응형