문제

JS의 모듈로 함수를 사용하여 계산을 시도하지만 올바른 결과(1이어야 함)를 얻지 못합니다.다음은 하드코딩된 코드입니다.

var checkSum = 210501700012345678131468;
alert(checkSum % 97);

Result: 66

여기서 문제는 무엇입니까?

안부, Benedikt

도움이 되었습니까?

해결책

Benedikt 버전의 개선 사항 : "Crest + = '' + Cdivident;" 버그 픽스입니다. Parseint (Divisor)는 두 인수를 문자열로 전달할 수있게합니다. 결국 빈 문자열을 확인하면 항상 숫자 값을 반환합니다. VAR 명령문이 추가되어 글로벌 변수를 사용하지 않습니다. Foreach를 구식 스타일로 변환하여 이전 JavaScript가있는 브라우저에서 작동합니다. 크레스트를 수정했습니다 == 0; 버그 (감사합니다 @dan.stackoverflow).

function modulo (divident, divisor) {
    var cDivident = '';
    var cRest = '';

    for (var i in divident ) {
        var cChar = divident[i];
        var cOperator = cRest + '' + cDivident + '' + cChar;

        if ( cOperator < parseInt(divisor) ) {
                cDivident += '' + cChar;
        } else {
                cRest = cOperator % divisor;
                if ( cRest == 0 ) {
                    cRest = '';
                }
                cDivident = '';
        }

    }
    cRest += '' + cDivident;
    if (cRest == '') {
        cRest = 0;
    }
    return cRest;
}

다른 팁

IBAN 계산의 경우 일반 은행 계좌 번호로 인해 문자열 데이터 유형에 매우 큰 숫자가 포함됩니다.이 큰 숫자에서 97로 나눈 나머지를 찾아야 합니다 -> 큰 숫자 % 97.

데이터 유형을 정수로 변환하자마자 오버플로가 발생하여 음의 정수가 발생하고 결국 잘못된 나머지 값이 발생합니다.(잘못된 결과를 초래하는) 장황한 코드 조각을 보았을 때 나는 내 코드를 공유하지 않을 수 없었습니다.크레딧은 다음으로 이동합니다. 정규수를 사용하여 매우 큰 수의 모듈러스 찾기

modulo: function(divident, divisor) {
    var partLength = 10;

    while (divident.length > partLength) {
        var part = divident.substring(0, partLength);
        divident = (part % divisor) +  divident.substring(partLength);          
    }

    return divident % divisor;
}

NB여기서는 JavaScript의 최대 정수 위치 15개(및 일부)보다 작기 때문에 10개 위치를 사용합니다. 결과적으로 97보다 큰 숫자가 나오고 근사한 숫자가 됩니다.처음 두 인수가 중요합니다.

당신이 이것에 희생 된 것 같습니다. 정밀도를 잃지 않고 숫자가 갈 수있는 JavaScript의 최고 정수 값은 무엇입니까?

다른 스레드의 내용을 반복하기 위해 :

그것들은 64 비트 플로팅 포인트 값이며, 가장 큰 정확한 적분 값은 2^53입니다. 그러나 사양 섹션에서 [8.5 : 숫자 유형] :

일부 ecmascript 연산자는 포괄적 인 범위 -2^31 ~ 2^31-1 범위 또는 0에서 2^32-1 범위에서 정수 만 처리합니다. 이 연산자는 숫자 유형의 모든 값을 허용하지만 먼저 각 값을 2^32 정수 값 중 하나로 변환합니다. 섹션 0과 0에서 각각 TOINT32 및 TOUINT32 연산자의 설명을 참조하십시오.

그러나 신용이 기한이 어디에 있는지 신용. 지미는 레그 워크 (글쎄, 인터넷 검색)에 대한 대답을 받아 들였다.

마지막으로 내 솔루션 :

function modulo (divident, divisor) {
    cDivident = '';
    cRest = '';

    for each ( var cChar in divident ) {
        cOperator = cRest + '' + cDivident + '' + cChar;

        if ( cOperator < divisor ) {
            cDivident += '' + cChar;
        } else {
            cRest = cOperator % divisor;
            if ( cRest == 0 ) cRest = '';
            cDivident = '';
        }

    }

    return cRest;
}

IBANS를 확인하기 위해 ES6에서 작업 (기능적) 솔루션을 복사 및 붙여 넣고 자하는 사람들을 위해 :

function isIBAN(s){
    const rearranged = s.substring(4,s.length) + s.substring(0,4);
    const numeric   = Array.from(rearranged).map(c =>(isNaN(parseInt(c)) ? (c.charCodeAt(0)-55).toString() : c)).join('');
    const remainder = Array.from(numeric).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % 97,0);

    return  remainder === 1;}

당신은 그것을 한 라이너로 쓸 수도 있습니다.

모듈로 작동은 실제 숫자를 저장하는 정수 배열에서 수행됩니다 (divident, 함수로 문자열로 적용) :

function modulo(divident, divisor){
   return Array.from(divident).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % divisor,0);
};

이것은 Modulo가 첨가, 하단 및 곱셈보다 분배되기 때문에 작동합니다.

  • (A+B)%M = ((A%M)+(B%M))%M
  • (ab)%m = ((a%m)-(b%m))%m
  • (ㅏb)%m = ((a%m)(b%m))%m

ES5로 변환 된 IBAN 기능은 다음과 같습니다.

function (s) {
    var rearranged = s.substring(4, s.length) + s.substring(0, 4);
    var numeric = Array.from(rearranged).map(function (c) { return (isNaN(parseInt(c)) ? (c.charCodeAt(0) - 55).toString() : c); }).join('');
    var remainder = Array.from(numeric).map(function (c) { return parseInt(c); }).reduce(function (remainder, value) { return (remainder * 10 + value) % 97; }, 0);
    return remainder === 1;
};

Silent Matt는 JavaScript를 개발했습니다 도서관 큰 정수. 이 문제도 해결할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top