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