Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript is giving a different answer to same algorithm in Python

I'm working on the Rosalind problem Mortal Fibonacci Rabbits and the website keeps telling me my answer is wrong when I use my algorithm written JavaScript. When I use the same algorithm in Python I get a different (and correct) answer.

The inconsistency only happens when the result gets large. For example fibd(90, 19) returns 2870048561233730600 in JavaScript but in Python I get 2870048561233731259.

Is there something about numbers in JavaScript that give me a different answer or am making a subtle mistake in my JavaScript code?

The JavaScript solution:

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

The Python solution:

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)
like image 877
Cristian Avatar asked Dec 10 '15 08:12

Cristian


2 Answers

I think Javascript only has a "Number" datatype, and this actually an IEEE double under the hood. 2,870,048,561,233,730,600 is too large to hold precisely in IEEE double, so it is approximated. (Notice the trailing "00" - 17 decimal places is about right for double.)

Python on the other hand has bignum support, and will quite cheerfully deal with 4096 bit integers (for those that play around with cryptographic algorithms, this is a huge boon).

You might will be able to find a Javascript bignum library if you search - for example http://silentmatt.com/biginteger/

like image 147
Martin Bonner supports Monica Avatar answered Nov 09 '22 23:11

Martin Bonner supports Monica


Just doing a bit of research, this article seems interesting. Javascript only supports 53bits integers.

The result given by Python is indeed out of the maximum safe range for JS. If you try to do

parseInt('2870048561233731259')

It will indeed return

2870048561233731000
like image 7
Simone Zandara Avatar answered Nov 10 '22 00:11

Simone Zandara