dartist / dart-bignum

Other
14 stars 11 forks source link

compareTo() doesn't work as expected #28

Closed dinhvh closed 10 years ago

dinhvh commented 10 years ago

When built with dart2js (I haven't checked with native Dart).

BigNumber e = new BigNumber(765495393);
print('${e.compareTo(BigInteger.ZERO)} ${e.compareTo(new BigInteger(2^32))}');

shows the following result:

73 72 

I expected the second value to be negative.

adam-singer commented 10 years ago

Honestly I'm not aware if dart2js fully works on all calls. I'll try to debug this but old issues filed on how shifting works when dart is compiled to javascript was hard to work around.

adam-singer commented 10 years ago

@dinhviethoa ahh, are you expectin ^ operator in dart to be pow or bitwise or?

adam-singer commented 10 years ago
import 'dart:math';

BigInteger e = new BigInteger(765495393);
print('${e.compareTo(BigInteger.ZERO)} ${e.compareTo(new BigInteger(pow(2,32)))}');
2 -14
dinhvh commented 10 years ago

Trying again then. Being confused by that operator...

adam-singer commented 10 years ago

https://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#operator_table

bitwise XOR ^

so 2^32 == 34

dinhvh commented 10 years ago

Here's my result:

import 'dart:math';

BigInteger e = new BigInteger(765495393);
BigInteger compareValue = new BigInteger(Mathx.pow(2,32) - 1);
compareValue = compareValue.subtract(e);
print('1: ${e.intValue()} ${e.compareTo(BigInteger.ZERO)} ${e.compareTo(new BigInteger(pow(2,32)))}');
print('2: ${e.intValue()} ${compareValue.intValue()} ${e.signum()} ${compareValue.signum()}');
1: 765495393 73 71
2: 765495393 3529471902 1 -1 
adam-singer commented 10 years ago

@dinhviethoa Thats really odd, I'm not seeing that result in dartvm, dartium or chrome (dart2js)

screen shot 2014-03-21 at 4 36 28 pm

import 'package:bignum/bignum.dart';
import 'dart:math';
void main() {

  BigInteger e = new BigInteger(765495393);
  BigInteger compareValue = new BigInteger(pow(2,32) - 1);
  compareValue = compareValue.subtract(e);
  print('1: ${e.intValue()} ${e.compareTo(BigInteger.ZERO)} ${e.compareTo(new BigInteger(pow(2,32)))}');
  print('2: ${e.intValue()} ${compareValue.intValue()} ${e.signum()} ${compareValue.signum()}');

}
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>simple</title>
  </head>

  <body>   
    <p id="text">asdf</p>
    <script type="application/dart" src="simple.dart"></script>
    <!-- for this next line to work, your pubspec.yaml file must have a dependency on 'browser' -->
    <script src="packages/browser/dart.js"></script>
  </body>
</html>
adam-singer commented 10 years ago

Checkout branch test_issue_28 https://github.com/financeCoding/dart-bignum/tree/test_issue_28

dinhvh commented 10 years ago

I tried to print those numbers. They are actually big: intValue() was not accurate.

print('${e} ${compareValue}');

971297549654966465471040186078526977874307755538469709141571508096878600330250408927942495830063072632507154628944916071991010232138269849663331043366836662528661908227401065520646828812858000000754584175342881004429906624585192108546197172785757823246111148556988835078011283642566982479590253797173142616130902378018142470529622362940901124542100233112871464514987893327347129866025327640225999747915240518779885411364371447907846755772464188964668727085084385744856627161003701391107535509437023601208360580415837511605277463991278561458553509568000153207192880136495675186710246284271913837076456735634754668641 -971297549654966465471040186078526977874307755538469709141571508096878600330250408927942495830063072632507154628944916071991010232138269849663331043366836662528661908227401065520646828812858000000754584175342881004429906624585192108546197172785757823246111148556988835078011283642566982479590253797173142616130902378018142470529622362940901124542100233112871464514987893327347129866025327640225999747915240518779885411364371447907846755772464188964668727085084385744856627161003701391107535509437023601208360580415837511605277463991278561458553509568000153207192880136495675186710246284271913837076456735630459701346
dinhvh commented 10 years ago

Thanks!

adam-singer commented 10 years ago

@dinhviethoa so does intValue() have a bug with it ?

dinhvh commented 10 years ago

intValue() probably overflows in javascript. (the max is probably 64bits). So that's an "expected" behavior. A warning in the console would probably help though I'm not sure if it's easy to do.

adam-singer commented 10 years ago

I think it should be possible with using identical(1, 1.0) bool hack.

izaera commented 10 years ago

Use this flag when running from the VM to catch javascript overflows:

--throw_on_javascript_int_overflow=true

Regarding shifting I'm still investigating it in https://github.com/izaera/cipher, but it seems that it doesn't work when run in Javascript. Specifically it seems that shifts in Javascript only support 32 bit signed integers, but the VM doesn't issue any warning.

I still have to make some checks and I will send a mail to misc-dart with my findings.