2015-12-10 3 views
9

Je travaille sur le problème Rosalind Mortal Fibonacci Rabbits et le site me répète que ma réponse est fausse quand j'utilise mon algorithme écrit en JavaScript. Quand j'utilise le même algorithme en Python, j'obtiens une réponse différente (et correcte).Javascript donne une réponse différente au même algorithme en Python

L'incohérence se produit uniquement lorsque le résultat devient important. Par exemple fibd(90, 19) renvoie 2870048561233730600 dans JavaScript mais en Python, j'obtiens 2870048561233731259.

Y at-il quelque chose à propos des chiffres en JavaScript qui me donne une réponse différente ou une erreur subtile dans mon code JavaScript?

La solution 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 solution 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

Pouvez-vous donner un exemple? Je cours votre code et il donne le même résultat pour l'entrée (10,10). Cependant, je peux voir une faute de frappe "rp.splice (0, 0, rp.reduce (fonction (e, s) {return s + e;}) - rP [0]);". Serait-ce cela? Sinon, y a-t-il un point de divergence? –

+0

Bon point. J'ai ajouté un exemple. Cela arrive sur des entrées plus grandes. Bonne prise sur la faute de frappe. Merci, mais ce n'est pas le problème. C'était juste moi qui essayais de faire les mêmes noms de variables en question et il me manquait juste une variable à mettre à jour. La faute de frappe est fixée maintenant – Cristian

Répondre

13

Je pense que Javascript seulement un "nombre" type de données, et cela en fait un IEEE à double sous le capot. 2,870,048,561,233,730,600 est trop grand pour contenir exactement en double IEEE, donc il est approximatif. (Notez que le "00" final - 17 décimales est à peu près correct pour le double.)

Python d'un autre côté a un support bignum, et traitera de manière plutôt joyeuse des entiers 4096 bits (pour ceux qui jouent avec des algorithmes cryptographiques, c'est un énorme avantage).

Vous pourrait sera en mesure de trouver une bibliothèque Javascript bignum si vous effectuez une recherche - par exemple http://silentmatt.com/biginteger/

7

Juste faire un peu de recherche, cet article semble intéressant. Le résultat donné par Python est en effet hors de la plage de sécurité maximale pour JS. Si vous essayez de faire

parseInt('2870048561233731259') 

Il sera en effet revenir

2870048561233731000