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

Side by Side Diff: runtime/lib/bigint.dart

Issue 821123003: Simplify double to bigint conversion. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | « no previous file | runtime/lib/double.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // Copyright 2009 The Go Authors. All rights reserved. 5 // Copyright 2009 The Go Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style 6 // Use of this source code is governed by a BSD-style
7 // license that can be found in the LICENSE file. 7 // license that can be found in the LICENSE file.
8 8
9 /* 9 /*
10 * Copyright (c) 2003-2005 Tom Wu 10 * Copyright (c) 2003-2005 Tom Wu
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // Allocate extra digits so the bigint can be reused. 51 // Allocate extra digits so the bigint can be reused.
52 static const int EXTRA_DIGITS = 4; 52 static const int EXTRA_DIGITS = 4;
53 53
54 // Min and max of non bigint values. 54 // Min and max of non bigint values.
55 static const int MIN_INT64 = (-1) << 63; 55 static const int MIN_INT64 = (-1) << 63;
56 static const int MAX_INT64 = 0x7fffffffffffffff; 56 static const int MAX_INT64 = 0x7fffffffffffffff;
57 57
58 // Bigint constant values. 58 // Bigint constant values.
59 // Note: Not declared as final in order to satisfy optimizer, which expects 59 // Note: Not declared as final in order to satisfy optimizer, which expects
60 // constants to be in canonical form (Smi). 60 // constants to be in canonical form (Smi).
61 static _Bigint ONE = new _Bigint()._setInt(1); 61 static _Bigint ONE = new _Bigint._fromInt(1);
62 62
63 // Digit conversion table for parsing. 63 // Digit conversion table for parsing.
64 static final Map<int, int> DIGIT_TABLE = _createDigitTable(); 64 static final Map<int, int> DIGIT_TABLE = _createDigitTable();
65 65
66 // Internal data structure. 66 // Internal data structure.
67 // TODO(regis): Remove the 3 native setters below and provide a constructor
68 // taking all 3 field values, which is equivalent to making the fields final.
67 bool get _neg native "Bigint_getNeg"; 69 bool get _neg native "Bigint_getNeg";
68 void set _neg(bool value) native "Bigint_setNeg"; 70 void set _neg(bool value) native "Bigint_setNeg";
69 int get _used native "Bigint_getUsed"; 71 int get _used native "Bigint_getUsed";
70 void set _used(int value) native "Bigint_setUsed"; 72 void set _used(int value) native "Bigint_setUsed";
71 Uint32List get _digits native "Bigint_getDigits"; 73 Uint32List get _digits native "Bigint_getDigits";
72 void set _digits(Uint32List value) native "Bigint_setDigits"; 74 void set _digits(Uint32List value) native "Bigint_setDigits";
73 75
74 // Factory returning an instance initialized to value 0. 76 // Factory returning an instance initialized to value 0.
75 factory _Bigint() native "Bigint_allocate"; 77 factory _Bigint() native "Bigint_allocate";
76 78
77 // Factory returning an instance initialized to an integer value. 79 // Factory returning an instance initialized to an integer value no larger
80 // than a Mint.
78 factory _Bigint._fromInt(int i) { 81 factory _Bigint._fromInt(int i) {
79 return new _Bigint()._setInt(i);
80 }
81
82 // Factory returning an instance initialized to a hex string.
83 factory _Bigint._fromHex(String s) {
rmacnak 2015/01/13 21:22:43 Was this used by int.parse before? Do we have a fa
regis 2015/01/13 21:29:30 Currently, we only use a C++ version: Bigint::NewF
84 return new _Bigint()._setHex(s);
85 }
86
87 // Factory returning an instance initialized to a double value given by its
88 // components.
89 factory _Bigint._fromDouble(int sign, int significand, int exponent) {
90 return new _Bigint()._setDouble(sign, significand, exponent);
91 }
92
93 // Initialize instance to the given value no larger than a Mint.
94 _Bigint _setInt(int i) {
95 assert(i is! _Bigint); 82 assert(i is! _Bigint);
96 _ensureLength(2); 83 bool neg;
97 _used = 2;
98 var l, h; 84 var l, h;
99 if (i < 0) { 85 if (i < 0) {
100 _neg = true; 86 neg = true;
101 if (i == MIN_INT64) { 87 if (i == MIN_INT64) {
102 l = 0; 88 l = 0;
103 h = 0x80000000; 89 h = 0x80000000;
104 } else { 90 } else {
105 l = (-i) & DIGIT_MASK; 91 l = (-i) & DIGIT_MASK;
106 h = (-i) >> DIGIT_BITS; 92 h = (-i) >> DIGIT_BITS;
107 } 93 }
108 } else { 94 } else {
109 _neg = false; 95 neg = false;
110 l = i & DIGIT_MASK; 96 l = i & DIGIT_MASK;
111 h = i >> DIGIT_BITS; 97 h = i >> DIGIT_BITS;
112 } 98 }
113 _digits[0] = l; 99 var result = new _Bigint();
114 _digits[1] = h; 100 result._ensureLength(2);
115 _clamp(); 101 result._neg = neg;
116 return this; 102 result._used = 2;
117 } 103 result._digits[0] = l;
118 104 result._digits[1] = h;
119 // Initialize instance to the given hex string. 105 result._clamp();
120 // TODO(regis): Copy Bigint::NewFromHexCString, fewer digit accesses. 106 return result;
121 // TODO(regis): Unused.
122 _Bigint _setHex(String s) {
123 const int HEX_BITS = 4;
124 const int HEX_DIGITS_PER_DIGIT = 8;
125 var hexDigitIndex = s.length;
126 _ensureLength((hexDigitIndex + HEX_DIGITS_PER_DIGIT - 1) ~/ HEX_DIGITS_PER_D IGIT);
127 var bitIndex = 0;
128 var digits = _digits;
129 while (--hexDigitIndex >= 0) {
130 var digit = DIGIT_TABLE[s.codeUnitAt(hexDigitIndex)];
131 if (digit = null) {
132 if (s[hexDigitIndex] == "-") _neg = true;
133 continue; // Ignore invalid digits.
134 }
135 _neg = false; // Ignore "-" if not at index 0.
136 if (bitIndex == 0) {
137 digits[_used++] = digit;
138 // TODO(regis): What if too many bad digits were ignored and
139 // _used becomes larger than _digits.length? error or reallocate?
140 } else {
141 digits[_used - 1] |= digit << bitIndex;
142 }
143 bitIndex = (bitIndex + HEX_BITS) % DIGIT_BITS;
144 }
145 _clamp();
146 return this;
147 }
148
149 // Initialize instance to the given double value.
150 _Bigint _setDouble(int sign, int significand, int exponent) {
151 assert(significand >= 0);
152 assert(exponent >= 0);
153 _setInt(significand);
154 _neg = sign < 0;
155 if (exponent > 0) {
156 _lShiftTo(exponent, this);
157 }
158 return this;
159 } 107 }
160 108
161 // Create digit conversion table for parsing. 109 // Create digit conversion table for parsing.
162 static Map<int, int> _createDigitTable() { 110 static Map<int, int> _createDigitTable() {
163 Map table = new HashMap(); 111 Map table = new HashMap();
164 int digit, value; 112 int digit, value;
165 digit = "0".codeUnitAt(0); 113 digit = "0".codeUnitAt(0);
166 for(value = 0; value <= 9; ++value) table[digit++] = value; 114 for(value = 0; value <= 9; ++value) table[digit++] = value;
167 digit = "a".codeUnitAt(0); 115 digit = "a".codeUnitAt(0);
168 for(value = 10; value < 36; ++value) table[digit++] = value; 116 for(value = 10; value < 36; ++value) table[digit++] = value;
(...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 other._toBigint()._mulTo(this, result); 1246 other._toBigint()._mulTo(this, result);
1299 return result._toValidInt(); 1247 return result._toValidInt();
1300 } 1248 }
1301 int _truncDivFromInteger(int other) { 1249 int _truncDivFromInteger(int other) {
1302 _Bigint result = new _Bigint(); 1250 _Bigint result = new _Bigint();
1303 other._toBigint()._divRemTo(this, result, null); 1251 other._toBigint()._divRemTo(this, result, null);
1304 return result._toValidInt(); 1252 return result._toValidInt();
1305 } 1253 }
1306 int _moduloFromInteger(int other) { 1254 int _moduloFromInteger(int other) {
1307 _Bigint result = new _Bigint(); 1255 _Bigint result = new _Bigint();
1308 var ob = other._toBigint();
1309 other._toBigint()._divRemTo(this, null, result); 1256 other._toBigint()._divRemTo(this, null, result);
1310 if (result._neg) { 1257 if (result._neg) {
1311 if (_neg) { 1258 if (_neg) {
1312 result._subTo(this, result); 1259 result._subTo(this, result);
1313 } else { 1260 } else {
1314 result._addTo(this, result); 1261 result._addTo(this, result);
1315 } 1262 }
1316 } 1263 }
1317 return result._toValidInt(); 1264 return result._toValidInt();
1318 } 1265 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 z._sqrTo(g[1], g2); 1321 z._sqrTo(g[1], g2);
1375 while (n <= km) { 1322 while (n <= km) {
1376 g[n] = new _Bigint(); 1323 g[n] = new _Bigint();
1377 z._mulTo(g2, g[n - 2], g[n]); 1324 z._mulTo(g2, g[n - 2], g[n]);
1378 n += 2; 1325 n += 2;
1379 } 1326 }
1380 } 1327 }
1381 var j = e._used - 1; 1328 var j = e._used - 1;
1382 var w; 1329 var w;
1383 var is1 = true; 1330 var is1 = true;
1384 var r = new _Bigint()._setInt(1); 1331 var r = new _Bigint._fromInt(1);
1385 var r2 = new _Bigint(); 1332 var r2 = new _Bigint();
1386 var t; 1333 var t;
1387 var e_digits = e._digits; 1334 var e_digits = e._digits;
1388 i = _nbits(e_digits[j]) - 1; 1335 i = _nbits(e_digits[j]) - 1;
1389 while (j >= 0) { 1336 while (j >= 0) {
1390 if (i >= k1) { 1337 if (i >= k1) {
1391 w = (e_digits[j] >> (i - k1)) & km; 1338 w = (e_digits[j] >> (i - k1)) & km;
1392 } else { 1339 } else {
1393 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i); 1340 w = (e_digits[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
1394 if (j > 0) { 1341 if (j > 0) {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1627 void _sqrTo(_Bigint x, _Bigint r) { 1574 void _sqrTo(_Bigint x, _Bigint r) {
1628 x._sqrTo(r); 1575 x._sqrTo(r);
1629 _reduce(r); 1576 _reduce(r);
1630 } 1577 }
1631 1578
1632 void _mulTo(_Bigint x, _Bigint y, _Bigint r) { 1579 void _mulTo(_Bigint x, _Bigint y, _Bigint r) {
1633 x._mulTo(y, r); 1580 x._mulTo(y, r);
1634 _reduce(r); 1581 _reduce(r);
1635 } 1582 }
1636 } 1583 }
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/double.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698