Index: sdk/lib/_internal/compiler/js_lib/js_number.dart |
diff --git a/sdk/lib/_internal/compiler/js_lib/js_number.dart b/sdk/lib/_internal/compiler/js_lib/js_number.dart |
index 03c68bb00022ebf28d6f7103ea52da1bb492476f..882291112a8be45beae786f8ce05f52ab83a5303 100644 |
--- a/sdk/lib/_internal/compiler/js_lib/js_number.dart |
+++ b/sdk/lib/_internal/compiler/js_lib/js_number.dart |
@@ -415,20 +415,24 @@ class JSInt extends JSNumber implements int, double { |
int modInverse(int m) { |
if (m is! int) throw new ArgumentError(m); |
if (m <= 0) throw new RangeError(m); |
- if (this == 0) return 0; |
- bool ac = m.isEven; |
+ if (m == 1) return 0; |
+ int t = this; |
+ if ((t < 0) || (t >= m)) t %= m; |
+ if (t == 1) return 1; |
+ final bool ac = m.isEven; |
+ if ((t == 0) || (ac && t.isEven)) throw new RangeError("Not coprime"); |
int u = m; |
- int v = this; |
+ int v = t; |
int a = 1, |
b = 0, |
c = 0, |
d = 1; |
- while (u != 0) { |
+ do { |
while (u.isEven) { |
u ~/= 2; |
if (ac) { |
if (!a.isEven || !b.isEven) { |
- a += this; |
+ a += t; |
b -= m; |
} |
a ~/= 2; |
@@ -441,7 +445,7 @@ class JSInt extends JSNumber implements int, double { |
v ~/= 2; |
if (ac) { |
if (!c.isEven || !d.isEven) { |
- c += this; |
+ c += t; |
d -= m; |
} |
c ~/= 2; |
@@ -459,11 +463,15 @@ class JSInt extends JSNumber implements int, double { |
if (ac) c -= a; |
d -= b; |
} |
+ } while (u != 0); |
+ if (v != 1) throw new RangeError("Not coprime"); |
+ if (d < 0) { |
+ d += m; |
+ if (d < 0) d += m; |
+ } else if (d > m) { |
+ d -= m; |
+ if (d > m) d -= m; |
} |
- if (v != 1) return 0; |
- if (d > m) return d - m; |
- if (d < 0) d += m; |
- if (d < 0) d += m; |
return d; |
} |