Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dart2js and spec disagree about numerics #1533

Closed
sethladd opened this issue Feb 4, 2012 · 24 comments
Closed

dart2js and spec disagree about numerics #1533

sethladd opened this issue Feb 4, 2012 · 24 comments
Assignees
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue web-dart2js

Comments

@sethladd
Copy link
Contributor

sethladd commented Feb 4, 2012

The following Dart code:

var x = 123;
print(x is! double);

will print TRUE in Dart VM and FALSE in JavaScript compiled from Frog.

The generated JavaScript code in question:

print((typeof(x) != 'number'));

doesn't match the intention of the original Dart code.

@DartBot
Copy link

DartBot commented Feb 4, 2012

This comment was originally written by jat@google.com


See also issue #638 and lengthy discussions on the mailing list last year.

@dgrove
Copy link
Contributor

dgrove commented Feb 5, 2012

Added Area-Frog, Triaged labels.

@gbracha
Copy link
Contributor

gbracha commented Mar 6, 2012

I'm generalizing this to tack the numeric discrepancies between the spec (and VM) and the Javascript based implementations.

Consider:

main() {
    int billion = 1000000000;
    int quintillion = billion * billion;
    int quintillionOne = quintillion + 1;
    print(quintillion == quintillionOne);
  }

It compiles without emitting a warning or error, and prints true, which clearly violates the principle of least astonishment.

WE may end up making allowances for JS in some way, but for now this is a bug, and we can track the issue here.


Changed the title to: "Frog and spec disagree about numerics".

@anders-sandholm
Copy link
Contributor

Removed Area-Frog label.
Added Area-Dart2JS, FromAreaFrog labels.

@kasperl
Copy link

kasperl commented Jun 12, 2012

Removed FromAreaFrog label.
Changed the title to: "dart2js and spec disagree about numerics".

@DartBot
Copy link

DartBot commented Jul 25, 2012

This comment was originally written by la...@randompage.org


We need arbitrary precision integers in our Dart program and have currently implemented our own integer class to get around this bug. Arbitrary precision makes sense for a modern programming language as it's would cause numeric overflows to be a thing of the past.

At any rate please provide some closure on if Dart's integers are arbitrary precision or not.

@sethladd
Copy link
Contributor Author

The spec says that integers are arbitrary precision. The open issue is how will dart2js accomplish this, with reasonable performance.

@floitschG
Copy link
Contributor

Issue #4478 has been merged into this issue.

@sethladd
Copy link
Contributor Author

Added this to the M1 milestone.
Removed Priority-Medium label.
Added Priority-High label.

@kasperl
Copy link

kasperl commented Aug 15, 2012

We do not plan to change the way we deal with ints in dart2js for M1. We will take a look at tackling issue #3814 and issue #4437, but general big int support is not something we're ready to tackle anytime soon.

It remains an issue so I'm certainly keeping the bug open.


Set owner to @kasperl.
Removed this from the M1 milestone.
Added this to the Later milestone.
Removed Priority-High label.
Added Priority-Medium, Accepted labels.

@kasperl
Copy link

kasperl commented Aug 15, 2012

cc @larsbak.

@floitschG
Copy link
Contributor

Issue #5827 has been merged into this issue.

@kasperl
Copy link

kasperl commented Oct 17, 2012

Removed this from the Later milestone.

@kasperl
Copy link

kasperl commented Oct 17, 2012

Added this to the Later milestone.

@DartBot
Copy link

DartBot commented Nov 9, 2012

This comment was originally written by ngeoffray@google.com


Issue #6627 has been merged into this issue.


cc @karlklose.

@fsc8000
Copy link
Contributor

fsc8000 commented Nov 9, 2012

Issue #6627 has been merged into this issue.

1 similar comment
@rakudrama
Copy link
Member

Issue #6627 has been merged into this issue.

@peter-ahe-google
Copy link
Contributor

Issue #7488 has been merged into this issue.

@gramster
Copy link
Contributor

For the record, I would like to note that merging bugs like 7488 and others with 1533 is fine as long as those other bugs are revisited when addressing this issue, as this issue seems to have largely become about whether dart2js will support bigints, and I don't think that that is the same as what issue #7488 is about, namely doubles without fractional parts being treated as ints by dart2js (and thus being legitimately used, for example, as indices into containers, while the VM will throw an exception).

@sigmundch sigmundch added closed-not-planned Closed as we don't intend to take action on the reported issue and removed accepted labels Dec 9, 2015
@sigmundch
Copy link
Member

I don't believe this is something we will change in dart2js. We need to map both int/double to Number to be able to generate code that performs well in JS engines.

We might want to be more explicit/upfront about these exceptions though. Either by making mention of them in the spec or in our documentation. Thoughts?

/cc @floitschG @kwalrath @gbracha

@homer-jay
Copy link

I'm new to Dart and I find the documentation extremely confusing. On the one hand it claims Dart has built in arbitrary precission integers, and this would actually be a plus for developers coming from other languages, something that might motivate them to learn Dart. On the other hand, this pad proves otherwise. In the end this pad shows a problem with numbers greater than JavaScript's MAX_SAFE_INTEGER.

Why is this discrepancy between "VM Dart" and "JS Dart" allowed to exist nowadays? Dart is Dart and it should behave the same in all platforms. Either remove big int support from the VM or add it to dart2js for the sake of sanity. It is not difficult to implement this in dart2js, just use JavaScript's Number type for safe integers and switch to a JS based big int implementation outside of that range. That way you could keep the current performance for safe integers.

@peter-ahe-google
Copy link
Contributor

@homer-jay try reaching out in one of these place: https://www.dartlang.org/community
In particular, I think this mailing list is a great place to ask questions like this: https://groups.google.com/a/dartlang.org/forum/#!forum/misc

@ds84182
Copy link
Contributor

ds84182 commented Jan 25, 2018

For anyone else who runs into issues with shifts with Dart2JS and DDC, there's a simple solution.

After doing any bitwise operation on a negative number the resulting number is an unsigned 32-bit integer. You can turn it into a signed 32-bit integer with .toSigned(32). Right shifts properly move the sign bit, but the sign in the JavaScript number gets discarded by Dart2JS and DDC. print(((-1 >> 1).toSigned(32) >> 1).toSigned(32)) yields -1 in both the VM (with and without big ints) and the web.

However, I do feel that this should be fixed. Since the VM is now moving to signed 64-bit integers, it would make sense to use at least signed 32-bit integers for bit operations on the web.

With some tests on Chrome and Edge, the result of ((-1) >> 1) << 0 (in JavaScript) preserves the sign bit, while ((-1) >> 1) >>> 0 (in JavaScript) (which is what Dart2JS and DDC emit) does not preserve the sign bit. Changing the latter to the former would give the web the same results that the VM would yield (at least when bit width isn't taken into account), and the web would be consistent with the behaviors JavaScript developers expect (-1 >> 1 yields -1 in JavaScript and 4294967295 in Dart compiled JavaScript).

This may become more of an issue in the future, so it would be great to know how much code depends on this weird behavior.

But anyways, I thought of some pros and cons.

Pros:

  • Unknown! I'd love to hear from someone who works on Dart2JS or DDC on why we have these differences!

Cons:

  • From a glance at code available on GitHub, most libraries use workarounds to get consistent behavior with bitwise operations on both the VM and web.
  • This problem has affected developers for years. (This is issue number 1533 out of 31972)
  • This problem has been one of the pain points from testing on Dartium and deploying to normal browsers. (Not as much as today thanks to DDC!)
  • Sharing code between the VM and the web is tricky. Since developers have Flutter, they'll notice these differences when they try to share logic between the two. A developer might run tests solely on the Dart VM for their common library because it's quicker than running tests in the browser, but they won't hit these weird bits until they use the library on the web.
  • Result differs from JavaScript, C, C++, Rust, Go, etc.

@sigmundch
Copy link
Member

@levifeldman we appreciate that you later edited and removed your earlier comment. In the future, please take a moment before posting comments to make sure the content has a respectful and constructive tone. It is really important for both developers and the community here.

Regarding bigint - please file a new issue if you have an example we can take a look and test. A code sample that can run in isolation outside the context of flutter is even better, as it will help the team get to the root cause of the issue faster.

Unrelated - I also wanted to take a moment to share an article that was recently added, which explains in more detail the difference in number semantics: https://dart.dev/guides/language/numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue web-dart2js
Projects
None yet
Development

No branches or pull requests