64bit number strangeness

8 views
Skip to first unread message

Richard Sepulveda

unread,
Nov 4, 2011, 10:23:24 AM11/4/11
to General Dart Discussion
I am seeing some strange results when working with big numbers.. I am
running the following code...

var hexDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "a",
"b", "c", "d", "e", "f"];

num myNum = 0x123456789ABCDEF0; // long long (64 bit value) 16
bytes
String str = "";

num cnum = myNum;
for( var i=0; i<16; ++i){
var ndx = cnum & 0x0f;
str = hexDigits[ndx] + str;
cnum = (cnum >> 4);
}

document.query("#message").innerHTML = "Next $
{myNum.toRadixString(16)} Pressed2 ${str}";

This is what i expect:
Next 123456789abcdef0 Pressed2 123456789abcdef0

This is what i am actually getting:
Next 123456789abcdf00 Pressed2 ffffffff9abcdf00

The first conversion using toRadixString is almost correct except for
some reason, it is missing the 3rd LSB nibble.
The second conversion is really messed up. Appears that the shift
right operator is only working on 32 bits.. And we are getting a carry
bit for any byte past 8.

Thanks for your response.

Richard Sepulveda

unread,
Nov 4, 2011, 10:25:03 AM11/4/11
to General Dart Discussion
I forgot to mention that i am running the latest Dart Editor package,
http://www.dartlang.org/news/2011/10/31/editor.html

Richard Sepulveda

unread,
Nov 4, 2011, 10:34:04 AM11/4/11
to General Dart Discussion
One more correction to my original post..

I meant 64 bits -> 8 bytes instead of 16 bytes... i was thinking
nibble but typed byte.

Sorry for any confusion.

On Nov 4, 8:25 am, Richard Sepulveda <rsepulve...@gmail.com> wrote:
> I forgot to mention that i am running the latest Dart Editor package,http://www.dartlang.org/news/2011/10/31/editor.html

Srdjan Mitrovic

unread,
Nov 4, 2011, 11:57:53 AM11/4/11
to Richard Sepulveda, General Dart Discussion
The code runs fine on Dart VM, but not on Dart-JS: http://try-dart-lang.appspot.com/s/97we

Note that Dart -> JS compiler is using Javascript's numbers and therefore cannot represent 64 bit integers exactly (it is using doubles). I think the results should be 123456789abcdef0 (Dart VM) or 123456789abcdedc (Dart JS).

Please file a bug, thank you.

Richard Sepulveda

unread,
Nov 4, 2011, 1:19:47 PM11/4/11
to General Dart Discussion
I assumed that Google had added special code to handle integers over
32 bits and wasn't relying on the
built-in JS Number code for that. The spec states that Dart has no
limit to the number of bits in a number.

I also assumed that a Dart program should run identical on the Dart VM
as on Dart JS.

I will file a bug. Thanks for your response.

On Nov 4, 9:57 am, Srdjan Mitrovic <srd...@google.com> wrote:
> The code runs fine on Dart VM, but not on Dart-JS:http://try-dart-lang.appspot.com/s/97we
>
> Note that Dart -> JS compiler is using Javascript's numbers and therefore
> cannot represent 64 bit integers exactly (it is using doubles). I think the
> results should be 123456789abcdef0 (Dart VM) or 123456789abcdedc (Dart JS).
>
> Please file a bug, thank you.
>

Bob Nystrom

unread,
Nov 7, 2011, 3:57:57 PM11/7/11
to Richard Sepulveda, General Dart Discussion
On Fri, Nov 4, 2011 at 10:19 AM, Richard Sepulveda <rsepu...@gmail.com> wrote:
I assumed that Google had added special code to handle integers over
32 bits and wasn't relying on the built-in JS Number code for that.

The challenge is that it's incredibly hard if not impossible to get good performance in JS if you do that. The trade-off is you can have fast code that fits within JS's numeric limitations or you can have slow code that's correct if you go over (I think?) 53 bits or whatever JS guarantees.

Our hunch is that the vast majority of the code you'd run in a browser doesn't exceed that limitation anyway, so it's better to be fast.
 
The spec states that Dart has no limit to the number of bits in a number.

Right. Fully spec-compliant Dart numbers are arbitrary-precision. The Dart->JS compiler isn't exactly following the spec here. I don't know if we have a fully clear way to document this fact right now so it's not surprising that you ran into this problem without realizing it. Sorry.


I also assumed that a Dart program should run identical on the Dart VM as on Dart JS.

This is an entirely reasonable assumption. It's correct 99% of the time, but large numbers are the exception. (There may be a couple of other exceptions too, but I can't think of them right now.) Any other time the VM and JS versions differ, it's a bug (and there are plenty of those).
 

I will file a bug. Thanks for your response.

Thanks for bringing this up! It's good to have a chance to clarify things here.

- bob

John Tamplin

unread,
Nov 7, 2011, 4:22:27 PM11/7/11
to Bob Nystrom, Richard Sepulveda, General Dart Discussion
On Mon, Nov 7, 2011 at 3:57 PM, Bob Nystrom <rnys...@google.com> wrote:
The challenge is that it's incredibly hard if not impossible to get good performance in JS if you do that. The trade-off is you can have fast code that fits within JS's numeric limitations or you can have slow code that's correct if you go over (I think?) 53 bits or whatever JS guarantees.

Our hunch is that the vast majority of the code you'd run in a browser doesn't exceed that limitation anyway, so it's better to be fast.

That may be, but the problem is when it is silently wrong.  If I write a financial application in Dart, right now I cannot use the built-in arbitrary precision and have to write my own in Dart (not making use of the functionality in the VM), which will be massively slower and take more memory.  I do not think this is an acceptable situation, but the Frog guys have stated they believe they can achieve fully spec-compliant ints with acceptable performance.

If this turns out not to be the case, I will again push for separating bigint from int so that only those uses that actually need arbitrary precision will pay for it, and so that there is one language which behaves according to spec (changing the spec as necessary) across all implementations.

--
John A. Tamplin
Software Engineer (GWT), Google

Bob Nystrom

unread,
Nov 7, 2011, 4:42:12 PM11/7/11
to John Tamplin, Richard Sepulveda, General Dart Discussion
On Mon, Nov 7, 2011 at 1:22 PM, John Tamplin <j...@google.com> wrote:
On Mon, Nov 7, 2011 at 3:57 PM, Bob Nystrom <rnys...@google.com> wrote:
The challenge is that it's incredibly hard if not impossible to get good performance in JS if you do that. The trade-off is you can have fast code that fits within JS's numeric limitations or you can have slow code that's correct if you go over (I think?) 53 bits or whatever JS guarantees.

Our hunch is that the vast majority of the code you'd run in a browser doesn't exceed that limitation anyway, so it's better to be fast.

That may be, but the problem is when it is silently wrong.

Yeah, that worries me too.
 
If I write a financial application in Dart, right now I cannot use the built-in arbitrary precision and have to write my own in Dart (not making use of the functionality in the VM), which will be massively slower and take more memory.  I do not think this is an acceptable situation, but the Frog guys have stated they believe they can achieve fully spec-compliant ints with acceptable performance.

That would definitely be the best of both worlds.
 

If this turns out not to be the case, I will again push for separating bigint from int so that only those uses that actually need arbitrary precision will pay for it, and so that there is one language which behaves according to spec (changing the spec as necessary) across all implementations.

I don't have a strong opinion on how the language should behave but I agree whatever we do, we should write it down precisely.

- bob

Rémi Forax

unread,
Nov 7, 2011, 5:36:21 PM11/7/11
to mi...@dartlang.org
The fact that the VM silently overflows is in my opinion very dangerous.
It introduces a mismatch between the VM type system and the Dart type system,
for the VM you have small integer and arbitrary precision integers but in the Dart type system
you have only ints.
One thing which is important when you design a language is to be able to provide
a good performance model (the term was first coin by Josh Bloch I think), i.e
a user should be able to predict or at least bound the time that the VM will spend in each functions,
clearly when small integers are converted to arbitrary precision ones you see a massive slowdown
this is a nefarious property for an implementation of a language.
Moreover, when your VM will be able to do a type inference/type checking at runtime,
it will create some paradox like the fact that floating point calculations will be faster
than integers one.
I don't say that never a Dart VM will be able to remove int checks and be as fast
as C or Java, I say that you have chosen the wrong side of the mountain
so it will take more times and it will be harder.


- bob


Rémi

John Tamplin

unread,
Nov 7, 2011, 5:57:25 PM11/7/11
to Rémi Forax, mi...@dartlang.org
On Mon, Nov 7, 2011 at 5:36 PM, Rémi Forax <fo...@univ-mlv.fr> wrote:
The fact that the VM silently overflows is in my opinion very dangerous.
It introduces a mismatch between the VM type system and the Dart type system,
for the VM you have small integer and arbitrary precision integers but in the Dart type system
you have only ints.

The VM doesn't overflow, it is a problem in the generated JS by Dartc. 

Rémi Forax

unread,
Nov 7, 2011, 6:06:20 PM11/7/11
to mi...@dartlang.org
On 11/07/2011 11:57 PM, John Tamplin wrote:
On Mon, Nov 7, 2011 at 5:36 PM, Rémi Forax <fo...@univ-mlv.fr> wrote:
The fact that the VM silently overflows is in my opinion very dangerous.
It introduces a mismatch between the VM type system and the Dart type system,
for the VM you have small integer and arbitrary precision integers but in the Dart type system
you have only ints.

The VM doesn't overflow, it is a problem in the generated JS by Dartc.

sorry, replace 'overflows' by 'detects overflow'

I think that the VM should overflow.



--
John A. Tamplin
Software Engineer (GWT), Google

Rémi

Reply all
Reply to author
Forward
0 new messages