mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 12:44:21 +00:00
Fix for issue 10534. Implement int.pow correctly using exponentiation by squaring.
Note that int.pow is now considerably slower than double.pow. R=floitsch@google.com Review URL: https://codereview.chromium.org//14619027 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22635 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
0b9c15a102
commit
d0c639e474
|
@ -164,12 +164,17 @@ class _IntegerImplementation {
|
|||
double toDouble() { return new _Double.fromInteger(this); }
|
||||
|
||||
int pow(int exponent) {
|
||||
double res = this.toDouble().pow(exponent);
|
||||
if (res.isInfinite) {
|
||||
// Use Bigint instead.
|
||||
throw "_IntegerImplementation.pow not implemented for large integers.";
|
||||
// Exponentiation by squaring.
|
||||
int base = this;
|
||||
int result = 1;
|
||||
while (exponent != 0) {
|
||||
if ((exponent & 1) == 1) {
|
||||
result *= base;
|
||||
}
|
||||
exponent >>= 1;
|
||||
base *= base;
|
||||
}
|
||||
return res.toInt();
|
||||
return result;
|
||||
}
|
||||
|
||||
String toStringAsFixed(int fractionDigits) {
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
import "dart:typed_data";
|
||||
|
||||
// A VM patch of the dart:math library.
|
||||
|
||||
// If [x] is an [int] and [exponent] is a non-negative [int], the result is
|
||||
// an [int], otherwise the result is a [double].
|
||||
patch num pow(num x, num exponent) {
|
||||
if (exponent is int) {
|
||||
if ((x is int) && (exponent is int) && (exponent >= 0)) {
|
||||
return x.pow(exponent);
|
||||
}
|
||||
// Double.pow will call exponent.toDouble().
|
||||
|
|
|
@ -85,14 +85,23 @@ var expectedResults =
|
|||
void main() {
|
||||
int exp = 0;
|
||||
for (int val in expectedResults) {
|
||||
Expect.equals(val, pow(2, exp++));
|
||||
Expect.equals(val, pow(2, exp));
|
||||
Expect.equals(val.toDouble(), pow(2, exp.toDouble()));
|
||||
exp++;
|
||||
}
|
||||
|
||||
// Optimize it.
|
||||
for (int i = 0; i < 8888; i++) {
|
||||
pow(2, 3);
|
||||
pow(2.0, 3.0);
|
||||
}
|
||||
exp = 0;
|
||||
for (int val in expectedResults) {
|
||||
Expect.equals(val, pow(2, exp++));
|
||||
Expect.equals(val, pow(2, exp));
|
||||
Expect.equals(val.toDouble(), pow(2, exp.toDouble()));
|
||||
exp++;
|
||||
}
|
||||
// Test Bigints.
|
||||
Expect.equals(5559917313492231481, pow(11, 18));
|
||||
Expect.equals(672749994932560009201, pow(11, 20));
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ io/process_exit_negative_test: Fail, OK # relies on a static error that is a war
|
|||
package/package_isolate_test: Skip # spawnUri does not work in dart2js. See issue 3051
|
||||
debugger/*: Skip # Do not run standalone vm debugger tests with dart2js.
|
||||
left_shift_bit_and_op_test: Skip # Integers exceed dart2js precision.
|
||||
pow_test: Skip # Precision > 53 bits.
|
||||
|
||||
[ $compiler == dart2js && $jscl ]
|
||||
assert_test: Fail, OK # Assumes unspecified fields on the AssertionError.
|
||||
|
|
Loading…
Reference in a new issue