Int64(int value) should not be sensitive to rounding errors (#26)

* Int64(int value) should not be sensitive to rounding errors

* fix error in test

* fix constructor

* new package version number
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9ec23ff..228c997 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.10.6
+
+* Fix `Int64([int value])` constructor to avoid rounding error on intermediate
+  results for large negative inputs when compiled to JavaScript. `new
+  Int64(-1000000000000000000)` used to produce the same value as
+  `Int64.parseInt("-1000000000000000001")`
+
 ## 0.10.5
 
 * Fix strong mode warning in overridden `compareTo()` methods.
diff --git a/lib/src/int64.dart b/lib/src/int64.dart
index cc78ab6..c25b8fa 100644
--- a/lib/src/int64.dart
+++ b/lib/src/int64.dart
@@ -128,7 +128,7 @@
     bool negative = false;
     if (value < 0) {
       negative = true;
-      value = -value - 1;
+      value = -value;
     }
     // Avoid using bitwise operations that in JavaScript coerce their input to
     // 32 bits.
@@ -138,12 +138,9 @@
     value -= v1 * 4194304;
     v0 = value;
 
-    if (negative) {
-      v0 = ~v0;
-      v1 = ~v1;
-      v2 = ~v2;
-    }
-    return Int64._masked(v0, v1, v2);
+    return negative
+        ? Int64._negate(_MASK & v0, _MASK & v1, _MASK2 & v2)
+        : Int64._masked(v0, v1, v2);
   }
 
   factory Int64.fromBytes(List<int> bytes) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 185275f..a80a13e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,9 +1,9 @@
 name: fixnum
-version: 0.10.5
+version: 0.10.6
 author: Dart Team <misc@dartlang.org>
 description: Library for 32- and 64-bit signed fixed-width integers.
 homepage: https://github.com/dart-lang/fixnum
 dev_dependencies:
   test: ^0.12.0
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
+  sdk: ">=1.8.3 <2.0.0-dev.infinity"
diff --git a/test/int64_test.dart b/test/int64_test.dart
index 4ae7aea..fbd008d 100644
--- a/test/int64_test.dart
+++ b/test/int64_test.dart
@@ -747,6 +747,20 @@
     expect(-(Int64.MIN_VALUE + new Int64(1)), Int64.MAX_VALUE);
   });
 
+  test("", () {
+    check(int n) {
+      // Sign change should commute with conversion.
+      expect(-new Int64(-n), new Int64(n));
+      expect(new Int64(-n), -new Int64(n));
+    }
+
+    check(10);
+    check(1000000000000000000);
+    check(9223372000000000000); // near Int64.MAX_VALUE, has exact double value
+    check(9223372036854775807); // Int64.MAX_VALUE, rounds up to -MIN_VALUE
+    check(-9223372036854775808); // Int64.MIN_VALUE
+  });
+
   group("parse", () {
     test("parseRadix10", () {
       checkInt(int x) {