flexxui / pscript

Python to JavaScript compiler
http://pscript.readthedocs.io
BSD 2-Clause "Simplified" License
260 stars 25 forks source link

Big integer #42

Closed Mister7F closed 4 years ago

Mister7F commented 4 years ago

Hello, There's a problem with big integer. In Javascript, when an integer become to large, it is transformed to a float. But in python the integers have no limit.

from pscript import py2js

def foo(a):
    print(99999999999999999999999999999999999999999)

print(py2js(foo))

Maybe can you use big int in JS instead of simple integer ? (But division, power (and other Math functions) will be broken)

_tmp_screenshot

almarklein commented 4 years ago

JavaScript does not distinguish between int and float; everything is a float, some just happen to be rounded. In Python there are two types, but ints resolve to float automatically on operations like division. It will be very hard to make Python ints be represented as BigInt, and will have all sorts of consequences, like Math functions won't work as you point out.

Therefore, I don't think this is a problem that PScript should (try to) solve. Instead, if you need integer numbers that do not fit in float64, just use BigInt in that usecase.

Mister7F commented 4 years ago

@almarklein Sorry for the late response, maybe can you use something like this to emulate python number inside pscript...

I think this project is really awesome, but it would be even better if it felt like a real python :)

(And can develop it on my free time and make a pull request if you are interested)

class PyNumber {
    constructor(value) {
        this.isInt = !(Number(value) % 1);
        this.value = this.isInt ? BigInt(value) : value;
    }

    add(number) {
        if (number.isInt && this.isInt) {
            return new PyNumber(this.value + number.value);
        } else {
            return new PyNumber(Number(this.value) + Number(number.value));
        }
    }

    pow (number) {
        if (number.isInt && this.isInt) {
            return new PyNumber(this.value ** number.value);
        } else {
            return new PyNumber(Math.pow(Number(this.value), Number(number.value)));
        }
    }
}

a = new PyNumber(1);
b = new PyNumber(2);
console.log(a.add(b));

a = new PyNumber(1.3);
b = new PyNumber(2);
console.log(a.add(b));

a = new PyNumber(2);
b = new PyNumber(2.4);
console.log(a.add(b));

a = new PyNumber(2);
b = new PyNumber(3);
console.log(a.pow(b));

a = new PyNumber(2.3);
b = new PyNumber(2);
console.log(a.pow(b));

a = new PyNumber(2);
b = new PyNumber(2.4);
console.log(a.pow(b));
almarklein commented 4 years ago

This could be a solution for your use-case, and if it works for you please go ahead :) But it's not suitable as a general solution because it generates a lot of overhead, making all operations with numbers slower.

I think this project is really awesome, but it would be even better if it felt like a real python :)

Yeah ... the problem is that PScript quite feels like Python, but it's not. We can make it feel more like Python, but it still won't be, so there will always be surprises like this ...

Mister7F commented 4 years ago

Ok, thank you for your answer :)