peterolson / BigInteger.js

An arbitrary length integer library for Javascript
The Unlicense
1.12k stars 187 forks source link

Wrong output on and() #153

Closed idofilus closed 6 years ago

idofilus commented 6 years ago

On chrome you can find the correct way: 6827581190108759180n & 0xfn === 12n

On bigInt: bigInt(6827581190108759180).and(0xf).value === 8

Seems like with few examples I tried, it always off by 4, but not 100% sure about it.

Yaffle commented 6 years ago

@idofilus try

bigInt('6827581190108759180').and(0xf).value === 8

6827581190108759180 equals 6827581190108759040

idofilus commented 6 years ago

@Yaffle Not sure I understand what you mean by

6827581190108759180 equals 6827581190108759040

6827581190108759180 = 1011110110000000111000011101011000101111001001001000100 10001100 6827581190108759040 = 1011110110000000111000011101011000101111001001001000100 00000000

Now if we will use the lowest bits that are different:

   10001100
&      1111
 ----------
       1100
Yaffle commented 6 years ago

@idofilus , in javascript the numbers are stored using the "double-precision floating point format" and so have 53 bits of precision, your source code will parsed and the value will be rounded.

idofilus commented 6 years ago

@Yaffle I understand, but it seems like V8 is emulating it as a even bigger than unsigned long long ?

For example, if you would try to increment with the max of Unsigned long long: 18446744073709551615 + 1 === 18446744073709552000

Values are rounded

But, using V8's BigInt it would be possible: 18446744073709551615n + 1n === 18446744073709551616n

Even: 18446744073709551615n * -1n - 10n === -18446744073709551625n

So, even tho your point is logical. It seems like BigInt is much bigger than this.

Yaffle commented 6 years ago

@idofilus , I agree. BigInt is much bigger. The expression bigInt(6827581190108759180) will be evaluated as a function call with number value, not BigInt value.

idofilus commented 6 years ago

@Yaffle I used BN.js to solve my case, they are using strings as input to probably overcome the issue you described. I guess this is the nature of this current library because of it. Maybe consider having to support as a string as well with unlimited number range ? Or at least let people know about limitation :) I mean, not sure if it's already mentioned here. But I'm doing pretty standard thing here (kind of) using the server with _uint64t and handling modification to number on the client side as well.

EDIT: My bad, seems you already supporting it.