evanw / skew

A web-first, cross-platform programming language with an optimizing compiler
https://evanw.github.io/skew-lang.org/
MIT License
413 stars 16 forks source link

Big numbers becomes bad on JavaScript target #8

Closed PifyZ closed 8 years ago

PifyZ commented 8 years ago

I recently needed big numbers on my code but I've some problems with it. So I made a simple test:

@export
var a = 6364136223846793005

Becomes:

(function() {
  a = 1284865837;
})();

Can this be solved?

Edit: after reading the documentation, int are on 32 bits. Any possibility to have a int64 type or something?

evanw commented 8 years ago

Thanks for the feedback! This is because integers in Skew are signed 32-bit integers. I used to have a warning but that made valid code like 0x80000000 cause warnings. I'll add it back as an error in this case.

Skew makes it easy for you to use external libraries, so you should be able to use an existing implementation such as https://mikemcl.github.io/bignumber.js/:

@import
const BigNumber dynamic

@export
var a = BigNumber.new("6364136223846793005")

@export
def test string {
  return a.toString()
}

Does that solve what you were trying to do?

evanw commented 8 years ago

If you're using big numbers a lot, you can also use Skew's operator overloading features to make these more natural to use:

@import
class BigNumber {
  def new(text string)
  def toString string

  @rename("add")
  def +(other BigNumber) BigNumber

  @rename("multiply")
  def *(other BigNumber) BigNumber
}

@export
def test string {
  var a = BigNumber.new("6364136223846793005")
  var b = BigNumber.new("3")
  a += b
  b = a * BigNumber.new("5")
  return b.toString
}

That compiles to this:

(function() {
  test = function() {
    var a = new BigNumber('6364136223846793005');
    var b = new BigNumber('3');
    a = a.add(b);
    b = a.multiply(new BigNumber('5'));
    return b.toString();
  };
})();
PifyZ commented 8 years ago

Thanks for the quick answer. BigNumber works as you said. I saw that I could use "double" too. :)

evanw commented 8 years ago

Using double doesn't actually work in your case:

@export
var a = 6364136223846793005.0

The generated JavaScript doesn't represent the same number:

(function() {
  a = 6364136223846793000;
})();

Doubles can only represent integers reliably up to 2^53: http://stackoverflow.com/questions/1848700.

PifyZ commented 8 years ago

Oh, you're right. Thanks.