OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011, 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 // VMOptions=--optimization-counter-threshold=5 --no-background-compilation |
| 5 |
| 6 library math_test; |
| 7 import "package:expect/expect.dart"; |
| 8 import 'dart:math'; |
| 9 |
| 10 void checkVeryClose(double a, double b) { |
| 11 // We find a ulp (unit in the last place) by shifting the original number |
| 12 // to the right. This only works if we are not too close to infinity or if |
| 13 // we work with denormals. |
| 14 // We special case for 0.0, but not for infinity. |
| 15 if (a == 0.0) { |
| 16 final minimalDouble = 4.9406564584124654e-324; |
| 17 Expect.equals(true, b.abs() <= minimalDouble); |
| 18 return; |
| 19 } |
| 20 if (b == 0.0) { |
| 21 // No need to look if they are close. Otherwise the check for 'a' above |
| 22 // would have triggered. |
| 23 Expect.equals(a, b); |
| 24 } |
| 25 final double shiftRightBy52 = 2.220446049250313080847263336181640625e-16; |
| 26 final double shiftedA = (a * shiftRightBy52).abs(); |
| 27 // Compared to 'a', 'shiftedA' is now ~1-2 ulp. |
| 28 |
| 29 final double limitLow = a - shiftedA; |
| 30 final double limitHigh = a + shiftedA; |
| 31 Expect.equals(false, a == limitLow); |
| 32 Expect.equals(false, a == limitHigh); |
| 33 Expect.equals(true, limitLow <= b); |
| 34 Expect.equals(true, b <= limitHigh); |
| 35 } |
| 36 |
| 37 const NaN = double.NAN; |
| 38 const Infinity = double.INFINITY; |
| 39 |
| 40 var samples = [ |
| 41 NaN, |
| 42 -Infinity, |
| 43 -3.0, // Odd integer |
| 44 -2.0, // Even integer |
| 45 -1.5, // Non-integer, magnitude > 1 |
| 46 -1.0, // Unit |
| 47 -0.5, // Non-integer, magnitude < 1. |
| 48 -0.0, |
| 49 0.5, // Non-integer, magnitude < 1. |
| 50 1.0, // Unit |
| 51 1.5, // Non-integer, magnitude > 1 |
| 52 2.0, // Even integer |
| 53 3.0, // Odd integer |
| 54 Infinity |
| 55 ]; |
| 56 |
| 57 test() { |
| 58 // Tests of pow(x, y): |
| 59 for (var d in samples) { |
| 60 // if `y` is zero (0.0 or -0.0), the result is always 1.0. |
| 61 Expect.identical(1.0, pow(d, 0.0), "$d"); |
| 62 Expect.identical(1.0, pow(d, -0.0), "$d"); |
| 63 } |
| 64 for (var d in samples) { |
| 65 // if `x` is 1.0, the result is always 1.0. |
| 66 Expect.identical(1.0, pow(1.0, d), "$d"); |
| 67 } |
| 68 for (var d in samples) { |
| 69 // otherwise, if either `x` or `y` is NaN then the result is NaN. |
| 70 if (d != 0.0) Expect.isTrue(pow(NaN, d).isNaN, "$d"); |
| 71 if (d != 1.0) Expect.isTrue(pow(d, NaN).isNaN, "$d"); |
| 72 } |
| 73 |
| 74 for (var d in samples) { |
| 75 // if `x` is a finite and strictly negative and `y` is a finite non-integer, |
| 76 // the result is NaN. |
| 77 if (d < 0 && !d.isInfinite) { |
| 78 Expect.isTrue(pow(d, 0.5).isNaN, "$d"); |
| 79 Expect.isTrue(pow(d, -0.5).isNaN, "$d"); |
| 80 Expect.isTrue(pow(d, 1.5).isNaN, "$d"); |
| 81 Expect.isTrue(pow(d, -1.5).isNaN, "$d"); |
| 82 } |
| 83 } |
| 84 |
| 85 for (var d in samples) { |
| 86 if (d < 0) { |
| 87 // if `x` is Infinity and `y` is strictly negative, the result is 0.0. |
| 88 Expect.identical(0.0, pow(Infinity, d), "$d"); |
| 89 } |
| 90 if (d > 0) { |
| 91 // if `x` is Infinity and `y` is strictly positive, the result is Infinity
. |
| 92 Expect.identical(Infinity, pow(Infinity, d), "$d"); |
| 93 } |
| 94 } |
| 95 |
| 96 for (var d in samples) { |
| 97 if (d < 0) { |
| 98 // if `x` is 0.0 and `y` is strictly negative, the result is Infinity. |
| 99 Expect.identical(Infinity, pow(0.0, d), "$d"); |
| 100 } |
| 101 if (d > 0) { |
| 102 // if `x` is 0.0 and `y` is strictly positive, the result is 0.0. |
| 103 Expect.identical(0.0, pow(0.0, d), "$d"); |
| 104 } |
| 105 } |
| 106 |
| 107 for (var d in samples) { |
| 108 if (!d.isInfinite && !d.isNaN) { |
| 109 var dint = d.toInt(); |
| 110 if (d == dint && dint.isOdd) { |
| 111 // if `x` is -Infinity or -0.0 and `y` is an odd integer, then the |
| 112 // result is`-pow(-x ,y)`. |
| 113 Expect.identical(-pow(Infinity, d), pow(-Infinity, d)); |
| 114 Expect.identical(-pow(0.0, d), pow(-0.0, d)); |
| 115 continue; |
| 116 } |
| 117 } |
| 118 // if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the |
| 119 // result is the same as `pow(-x , y)`. |
| 120 Expect.identical(pow(Infinity, d), pow(-Infinity, d)); |
| 121 Expect.identical(pow(0.0, d), pow(-0.0, d)); |
| 122 } |
| 123 |
| 124 for (var d in samples) { |
| 125 |
| 126 if (d.abs() < 1) { |
| 127 // if `y` is Infinity and the absolute value of `x` is less than 1, the |
| 128 // result is 0.0. |
| 129 Expect.identical(0.0, pow(d, Infinity)); |
| 130 } else if (d.abs() > 1) { |
| 131 // if `y` is Infinity and the absolute value of `x` is greater than 1, |
| 132 // the result is Infinity. |
| 133 Expect.identical(Infinity, pow(d, Infinity)); |
| 134 } else if (d == -1) { |
| 135 // if `y` is Infinity and `x` is -1, the result is 1.0. |
| 136 Expect.identical(1.0, pow(d, Infinity)); |
| 137 } |
| 138 // if `y` is -Infinity, the result is `1/pow(x, Infinity)`. |
| 139 Expect.identical(1/pow(d, Infinity), pow(d, -Infinity)); |
| 140 } |
| 141 |
| 142 // Some non-exceptional values. |
| 143 checkVeryClose(16.0, pow(4.0, 2.0)); |
| 144 checkVeryClose(SQRT2, pow(2.0, 0.5)); |
| 145 checkVeryClose(SQRT1_2, pow(0.5, 0.5)); |
| 146 // Denormal result. |
| 147 Expect.identical(5e-324, pow(2.0, -1074.0)); |
| 148 // Overflow. |
| 149 Expect.identical(Infinity, pow(10.0, 309.0)); |
| 150 // Underflow. |
| 151 Expect.identical(0.0, pow(10.0, -325.0)); |
| 152 |
| 153 // Conversion to double. |
| 154 |
| 155 // The second argument is an odd integer as int, but not when converted |
| 156 // to double. |
| 157 Expect.identical(Infinity, pow(-0.0, -9223372036854775809)); |
| 158 } |
| 159 |
| 160 main() { |
| 161 for (int i = 0; i < 10; i++) test(); |
| 162 } |
OLD | NEW |