Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1146)

Side by Side Diff: pkg/math/lib/math.dart

Issue 541523002: pkg/math: remove placeholder (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/math/LICENSE ('k') | pkg/math/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dart.pkg.math;
6
7 /**
8 * Computes the greatest common divisor between [a] and [b].
9 *
10 * The result is always positive even if either `a` or `b` is negative.
11 */
12 int gcd(int a, int b) {
13 if (a == null) throw new ArgumentError(a);
14 if (b == null) throw new ArgumentError(b);
15 a = a.abs();
16 b = b.abs();
17
18 // Iterative Binary GCD algorithm.
19 if (a == 0) return b;
20 if (b == 0) return a;
21 int powerOfTwo = 1;
22 while (((a | b) & 1) == 0) {
23 powerOfTwo *= 2;
24 a ~/= 2;
25 b ~/= 2;
26 }
27
28 while (a.isEven) a ~/= 2;
29
30 do {
31 while (b.isEven) b ~/= 2;
32 if (a > b) {
33 int temp = b;
34 b = a;
35 a = temp;
36 }
37 b -= a;
38 } while (b != 0);
39
40 return a * powerOfTwo;
41 }
42
43 /**
44 * Computes the greatest common divisor between [a] and [b], as well as [x] and
45 * [y] such that `ax+by == gcd(a,b)`.
46 *
47 * The return value is a List of three ints: the greatest common divisor, `x`,
48 * and `y`, in that order.
49 */
50 List<int> gcdext(int a, int b) {
51 if (a == null) throw new ArgumentError(a);
52 if (b == null) throw new ArgumentError(b);
53
54 if (a < 0) {
55 List<int> result = gcdext(-a, b);
56 result[1] = -result[1];
57 return result;
58 }
59 if (b < 0) {
60 List<int> result = gcdext(a, -b);
61 result[2] = -result[2];
62 return result;
63 }
64
65 int r0 = a;
66 int r1 = b;
67 int x0, x1, y0, y1;
68 x0 = y1 = 1;
69 x1 = y0 = 0;
70
71 while (r1 != 0) {
72 int q = r0 ~/ r1;
73 int tmp = r0;
74 r0 = r1;
75 r1 = tmp - q*r1;
76
77 tmp = x0;
78 x0 = x1;
79 x1 = tmp - q*x1;
80
81 tmp = y0;
82 y0 = y1;
83 y1 = tmp - q*y1;
84 }
85
86 return new List<int>(3)
87 ..[0] = r0
88 ..[1] = x0
89 ..[2] = y0;
90 }
91
92 /**
93 * Computes the inverse of [a] modulo [m].
94 *
95 * Throws an [IntegerDivisionByZeroException] if `a` has no inverse modulo `m`:
96 *
97 * invert(4, 7); // 2
98 * invert(4, 10); // throws IntegerDivisionByZeroException
99 */
100 int invert(int a, int m) {
101 List<int> results = gcdext(a, m);
102 int g = results[0];
103 int x = results[1];
104 if (g != 1) {
105 throw new IntegerDivisionByZeroException();
106 }
107 return x % m;
108 }
109
110 /**
111 * Computes the least common multiple between [a] and [b].
112 */
113 int lcm(int a, int b) {
114 if (a == null) throw new ArgumentError(a);
115 if (b == null) throw new ArgumentError(b);
116 if (a == 0 && b == 0) return 0;
117
118 return a.abs() ~/ gcd(a, b) * b.abs();
119 }
120
121 /**
122 * Computes [base] raised to [exp] modulo [mod].
123 *
124 * The result is always positive, in keeping with the behavior of modulus
125 * operator (`%`).
126 *
127 * Throws an [IntegerDivisionByZeroException] if `exp` is negative and `base`
128 * has no inverse modulo `mod`.
129 */
130 int powmod(int base, int exp, int mod) {
131 if (base == null) throw new ArgumentError(base);
132 if (exp == null) throw new ArgumentError(exp);
133 if (mod == null) throw new ArgumentError(mod);
134
135 // Right-to-left binary method of modular exponentiation.
136 if (exp < 0) {
137 base = invert(base, mod);
138 exp = -exp;
139 }
140 if (exp == 0) { return 1; }
141
142 int result = 1;
143 base = base % mod;
144 while (true) {
145 if (exp.isOdd) {
146 result = (result * base) % mod;
147 }
148 exp ~/= 2;
149 if (exp == 0) {
150 return result;
151 }
152 base = (base * base) % mod;
153 }
154 }
OLDNEW
« no previous file with comments | « pkg/math/LICENSE ('k') | pkg/math/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698