Domanda

cerco di calcolare con funzione modulo JS', ma non ottengo il risultato giusto (che dovrebbe essere 1). Ecco un pezzo hardcoded di codice.

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

Result: 66

Che cosa è il problema qui?

Saluti, Benedikt

È stato utile?

Soluzione

Un po 'di miglioramenti alla versione di Benedikt: "Crest + = '' + cDivident;" è un bugfix; parseInt (divisore) consente di passare entrambi gli argomenti come stringhe; controllare la stringa vuota alla fine lo rende sempre ritorno valori numerici; aggiunto dichiarazioni var quindi non è utilizzando le variabili globali; foreach convertito in vecchio stile per quindi funziona nei browser con Javascript anziani; fissa la cresta == 0; bug (grazie @ 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;
}

Altri suggerimenti

Per un calcolo IBAN formare un normale numero ContoCorrente io alla fine con un numero molto elevato contenuto in un tipo di dati stringa. Da questo grande numero devo trovare il resto quando diviso per 97 -.> Gran numero% 97

Non appena ho convertire il tipo di dati in un intero ottengo un overflow con conseguente un intero negativo e, infine, un valore di riposo sbagliata. Come ho visto alcuni pezzi di codice verbose (che ha dato anche il risultato sbagliato), non ho potuto resistere a condividere la mia. Crediti vanno a Trovare Modulo di un numero molto grande con un numero normale

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. Io uso 10 posizioni qui come questo è più piccola delle 15 (e alcune) le posizioni di massimo numero intero in JavaScript, si traduce in un numero più grande di 97 ed è un bel numero tondo. I primi due argomenti importanti.

Sembra che tu sei caduto vittima di questo: Qual è il più alto valore intero di JavaScript che un numero può andare senza perdere precisione?

solo ribadire ciò che è in altro thread:

  

sono valori a virgola mobile a 64 bit, il più grande valore integrale esatto è 2 ^ 53. tuttavia, dalla sezione specifica [8.5: Numero Tipo]:

     

Alcuni operatori ECMAScript accordo solo con numeri interi nella gamma -2 ^ 31 a 2 ^ 31-1, inclusiva, o tra 0 e 2 ^ 32-1, inclusiva. Questi operatori accettano qualsiasi valore di tipo Number ma prima convertire ogni tale valore a uno di 2 ^ 32 valori interi. Vedere le descrizioni degli operatori ToInt32 e ToUint32 nelle sezioni 0 e 0, rispettivamente,

Ma credito quando il credito è dovuto. Jimmy ha ottenuto la risposta accettata là per fare la noia (beh, googling).

Infine, la mia soluzione:

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;
}

Per coloro che vogliono semplicemente copiare e incollare una soluzione di lavoro (funzionale) in ES6 per controllare IBAN:

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;}

È anche potrebbe scrivere come un one-liner.

L'operazione modulo viene eseguita sulla matrice di interi memorizzazione del numero reale (divident, applicato come stringa di funzionare):

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

Questo funziona perché Modulo è distributiva oltre addizione, sottrazione e moltiplicazione:

  • (a + b)% m = ((a% m) + (b% m))% m
  • (a-b)% m = ((a% m) - (b% m))% m
  • ( b)% m = ((a% m) (b% m))% m

La funzione IBAN transpiled per ES5 appare come:

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;
};

Silenzioso Matt ha sviluppato un Javascript libreria per grandi numeri interi. Si potrebbe risolvere questo problema anche.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top