| Index: runtime/lib/math_patch.dart
|
| diff --git a/runtime/lib/math_patch.dart b/runtime/lib/math_patch.dart
|
| index 1bf701d0750d746d8e287ad8e20fdfa6d4c03e97..89460cc394afe746a87413747eebed0174879bba 100644
|
| --- a/runtime/lib/math_patch.dart
|
| +++ b/runtime/lib/math_patch.dart
|
| @@ -10,10 +10,42 @@ import "dart:typed_data";
|
| // an [int], otherwise the result is a [double].
|
| patch num pow(num x, num exponent) {
|
| if ((x is int) && (exponent is int) && (exponent >= 0)) {
|
| - return x.pow(exponent);
|
| + return _intPow(x, exponent);
|
| }
|
| - // Double.pow will call exponent.toDouble().
|
| - return x.toDouble().pow(exponent);
|
| + // doublePow will call exponent.toDouble().
|
| + return _doublePow(x.toDouble(), exponent);
|
| +}
|
| +
|
| +double _doublePow(double base, num exponent) {
|
| + if (exponent == 0) {
|
| + return 1.0; // ECMA-262 15.8.2.13
|
| + }
|
| + if (exponent is! num) {
|
| + throw new ArgumentError(null);
|
| + }
|
| + double doubleExponent = exponent.toDouble();
|
| + if (base.isNaN || exponent.isNaN) {
|
| + return double.NAN;
|
| + }
|
| + return _pow(base, doubleExponent);
|
| +}
|
| +
|
| +double _pow(double base, double exponent) native "Math_doublePow";
|
| +
|
| +int _intPow(int base, int exponent) {
|
| + // Exponentiation by squaring.
|
| + int result = 1;
|
| + while (exponent != 0) {
|
| + if ((exponent & 1) == 1) {
|
| + result *= base;
|
| + }
|
| + exponent >>= 1;
|
| + // Skip unnecessary operation (can overflow to Mint or Bigint).
|
| + if (exponent != 0) {
|
| + base *= base;
|
| + }
|
| + }
|
| + return result;
|
| }
|
|
|
| patch double atan2(num a, num b) => _atan2(a.toDouble(), b.toDouble());
|
|
|