2015-12-10 29 views
9

Sto lavorando al problema Rosalind Mortal Fibonacci Rabbits e il sito web continua a dirmi che la mia risposta è sbagliata quando uso il mio algoritmo scritto JavaScript. Quando uso lo stesso algoritmo in Python ottengo una risposta diversa (e corretta).Javascript sta dando una risposta diversa allo stesso algoritmo in Python

L'incoerenza si verifica solo quando il risultato diventa ampio. Ad esempio fibd(90, 19) restituisce 2870048561233730600 in JavaScript ma in Python ottengo 2870048561233731259.

C'è qualcosa nei numeri in JavaScript che mi dà una risposta diversa o sto facendo un piccolo errore nel mio codice JavaScript?

La soluzione JavaScript:

function fibd(n, m) { 
    // Create an array of length m and set all elements to 0 
    var rp = new Array(m); 
    rp = rp.map(function(e) { return 0; }); 
    rp[0] = 1; 

    for (var i = 1; i < n; i++) { 
     // prepend the sum of all elements from 1 to the end of the array 
     rp.splice(0, 0, rp.reduce(function (e, s) { return s + e; }) - rp[0]); 
     // Remove the final element 
     rp.pop(); 
    } 

    // Sum up all the elements 
    return rp.reduce(function (e, s) { return s + e; }); 
} 

La soluzione Python:

def fibd(n, m): 
    # Create an array of length m and set all elements to 0 
    rp = [0] * m 
    rp[0] = 1 

    for i in range(n-1): 
     # The sum of all elements from 1 the end and dropping the final element 
     rp = [sum(rp[1:])] + rp[:-1] 

    return sum(rp) 
+0

Può fare un esempio? Corro il tuo codice e dà lo stesso risultato per l'input (10,10). Tuttavia posso vedere un errore di battitura "rp.splice (0, 0, rp.reduce (funzione (e, s) {return s + e;}) - rP [0]);". Potrebbe essere? Se no, c'è un punto di divergenza? –

+0

Buon punto. Ho aggiunto un esempio. Succede su input più grandi. Buona cattura sull'errore di battitura. Grazie, ma non è questo il problema. Ero solo io che cercavo di rendere identici i nomi delle variabili in questione e mi mancava solo una variabile da aggiornare. L'errore di battitura è ora risolto – Cristian

risposta

13

penso Javascript ha solo un tipo di dati "Numero", e questo in realtà un doppio IEEE sotto il cofano. 2.870.048.561.233.730.600 è troppo grande per contenere precisamente il doppio IEEE, quindi è approssimato. (Notare che il "00" finale corrisponde a 17 cifre decimali).

Python invece ha il supporto bignum e si occuperà in modo abbastanza allegro di interi a 4096 bit (per quelli che giocano con algoritmi crittografici, questo è un enorme vantaggio).

È forza sarà in grado di trovare una libreria JavaScript bignum se si cerca - per esempio http://silentmatt.com/biginteger/

7

Basta fare un po 'di ricerca, questo articolo sembra interessante. Javascript only supports 53bits integers.

Il risultato dato da Python è effettivamente al di fuori della gamma massima di sicurezza per JS. Se si tenta di fare

parseInt('2870048561233731259') 

Sarà infatti tornare

2870048561233731000