| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, 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 /** | |
| 6 * Mathematical constants and functions, plus a random number generator. | |
| 7 */ | |
| 8 library dart.math; | |
| 9 import 'dart:_foreign_helper' show JS; | |
| 10 import 'dart:_js_helper' show patch, checkNum; | |
| 11 | |
| 12 part "jenkins_smi_hash.dart"; | |
| 13 part "point.dart"; | |
| 14 part "random.dart"; | |
| 15 part "rectangle.dart"; | |
| 16 | |
| 17 /** | |
| 18 * Base of the natural logarithms. | |
| 19 * | |
| 20 * Typically written as "e". | |
| 21 */ | |
| 22 const double E = 2.718281828459045; | |
| 23 | |
| 24 /** | |
| 25 * Natural logarithm of 10. | |
| 26 */ | |
| 27 const double LN10 = 2.302585092994046; | |
| 28 | |
| 29 /** | |
| 30 * Natural logarithm of 2. | |
| 31 */ | |
| 32 const double LN2 = 0.6931471805599453; | |
| 33 | |
| 34 /** | |
| 35 * Base-2 logarithm of [E]. | |
| 36 */ | |
| 37 const double LOG2E = 1.4426950408889634; | |
| 38 | |
| 39 /** | |
| 40 * Base-10 logarithm of [E]. | |
| 41 */ | |
| 42 const double LOG10E = 0.4342944819032518; | |
| 43 | |
| 44 /** | |
| 45 * The PI constant. | |
| 46 */ | |
| 47 const double PI = 3.1415926535897932; | |
| 48 | |
| 49 /** | |
| 50 * Square root of 1/2. | |
| 51 */ | |
| 52 const double SQRT1_2 = 0.7071067811865476; | |
| 53 | |
| 54 /** | |
| 55 * Square root of 2. | |
| 56 */ | |
| 57 const double SQRT2 = 1.4142135623730951; | |
| 58 | |
| 59 /** | |
| 60 * Returns the lesser of two numbers. | |
| 61 * | |
| 62 * Returns NaN if either argument is NaN. | |
| 63 * The lesser of [:-0.0:] and [:0.0:] is [:-0.0:]. | |
| 64 * If the arguments are otherwise equal (including int and doubles with the | |
| 65 * same mathematical value) then it is unspecified which of the two arguments | |
| 66 * is returned. | |
| 67 */ | |
| 68 num min(num a, num b) { | |
| 69 // These partially redundant type checks improve code quality for dart2js. | |
| 70 // Most of the improvement is at call sites from the inferred non-null num | |
| 71 // return type. | |
| 72 if (a is! num) throw new ArgumentError(a); | |
| 73 if (b is! num) throw new ArgumentError(b); | |
| 74 | |
| 75 if (a > b) return b; | |
| 76 if (a < b) return a; | |
| 77 if (b is double) { | |
| 78 // Special case for NaN and -0.0. If one argument is NaN return NaN. | |
| 79 // [min] must also distinguish between -0.0 and 0.0. | |
| 80 if (a is double) { | |
| 81 if (a == 0.0) { | |
| 82 // a is either 0.0 or -0.0. b is either 0.0, -0.0 or NaN. | |
| 83 // The following returns -0.0 if either a or b is -0.0, and it | |
| 84 // returns NaN if b is NaN. | |
| 85 return (a + b) * a * b; | |
| 86 } | |
| 87 } | |
| 88 // Check for NaN and b == -0.0. | |
| 89 if (a == 0 && b.isNegative || b.isNaN) return b; | |
| 90 return a; | |
| 91 } | |
| 92 return a; | |
| 93 } | |
| 94 | |
| 95 /** | |
| 96 * Returns the larger of two numbers. | |
| 97 * | |
| 98 * Returns NaN if either argument is NaN. | |
| 99 * The larger of [:-0.0:] and [:0.0:] is [:0.0:]. If the arguments are | |
| 100 * otherwise equal (including int and doubles with the same mathematical value) | |
| 101 * then it is unspecified which of the two arguments is returned. | |
| 102 */ | |
| 103 num max(num a, num b) { | |
| 104 // These partially redundant type checks improve code quality for dart2js. | |
| 105 // Most of the improvement is at call sites from the inferred non-null num | |
| 106 // return type. | |
| 107 if (a is! num) throw new ArgumentError(a); | |
| 108 if (b is! num) throw new ArgumentError(b); | |
| 109 | |
| 110 if (a > b) return a; | |
| 111 if (a < b) return b; | |
| 112 if (b is double) { | |
| 113 // Special case for NaN and -0.0. If one argument is NaN return NaN. | |
| 114 // [max] must also distinguish between -0.0 and 0.0. | |
| 115 if (a is double) { | |
| 116 if (a == 0.0) { | |
| 117 // a is either 0.0 or -0.0. b is either 0.0, -0.0, or NaN. | |
| 118 // The following returns 0.0 if either a or b is 0.0, and it | |
| 119 // returns NaN if b is NaN. | |
| 120 return a + b; | |
| 121 } | |
| 122 } | |
| 123 // Check for NaN. | |
| 124 if (b.isNaN) return b; | |
| 125 return a; | |
| 126 } | |
| 127 // max(-0.0, 0) must return 0. | |
| 128 if (b == 0 && a.isNegative) return b; | |
| 129 return a; | |
| 130 } | |
| 131 | |
| 132 /** | |
| 133 * A variant of [atan]. | |
| 134 * | |
| 135 * Converts both arguments to doubles. | |
| 136 * | |
| 137 * Returns the angle between the positive x-axis and the vector ([b],[a]). | |
| 138 * The result, in radians, is in the range -PI..PI. | |
| 139 * | |
| 140 * If [b] is positive, this is the same as [:atan(b/a):]. | |
| 141 * | |
| 142 * The result is negative when [a] is negative (including when [a] is the | |
| 143 * double -0.0). | |
| 144 * | |
| 145 * If [a] is equal to zero, the vector ([b],[a]) is considered parallel to | |
| 146 * the x-axis, even if [b] is also equal to zero. The sign of [b] determines | |
| 147 * the direction of the vector along the x-axis. | |
| 148 * | |
| 149 * Returns NaN if either argument is NaN. | |
| 150 */ | |
| 151 double atan2(num a, num b) | |
| 152 => JS('double', r'Math.atan2(#, #)', checkNum(a), checkNum(b)); | |
| 153 | |
| 154 /** | |
| 155 * Returns [x] to the power of [exponent]. | |
| 156 * | |
| 157 * If [x] is an [int] and [exponent] is a non-negative [int], the result is | |
| 158 * an [int], otherwise both arguments are converted to doubles first, and the | |
| 159 * result is a [double]. | |
| 160 * | |
| 161 * For integers, the power is always equal to the mathematical result of `x` to | |
| 162 * the power `exponent`, only limited by the available memory. | |
| 163 * | |
| 164 * For doubles, `pow(x, y)` handles edge cases as follows: | |
| 165 * | |
| 166 * - if `y` is zero (0.0 or -0.0), the result is always 1.0. | |
| 167 * - if `x` is 1.0, the result is always 1.0. | |
| 168 * - otherwise, if either `x` or `y` is NaN then the result is NaN. | |
| 169 * - if `x` is negative (but not -0.0) and `y` is a finite non-integer, the | |
| 170 * result is NaN. | |
| 171 * - if `x` is Infinity and `y` is negative, the result is 0.0. | |
| 172 * - if `x` is Infinity and `y` is positive, the result is Infinity. | |
| 173 * - if `x` is 0.0 and `y` is negative, the result is Infinity. | |
| 174 * - if `x` is 0.0 and `y` is positive, the result is 0.0. | |
| 175 * - if `x` is -Infinity or -0.0 and `y` is an odd integer, then the result is | |
| 176 * `-pow(-x ,y)`. | |
| 177 * - if `x` is -Infinity or -0.0 and `y` is not an odd integer, then the result | |
| 178 * is the same as `pow(-x , y)`. | |
| 179 * - if `y` is Infinity and the absolute value of `x` is less than 1, the | |
| 180 * result is 0.0. | |
| 181 * - if `y` is Infinity and `x` is -1, the result is 1.0. | |
| 182 * - if `y` is Infinity and the absolute value of `x` is greater than 1, | |
| 183 * the result is Infinity. | |
| 184 * - if `y` is -Infinity, the result is `1/pow(x, Infinity)`. | |
| 185 * | |
| 186 * This corresponds to the `pow` function defined in the IEEE Standard 754-2008. | |
| 187 * | |
| 188 * Notice that an [int] result cannot overflow, but a [double] result might | |
| 189 * be [double.INFINITY]. | |
| 190 */ | |
| 191 num pow(num x, num exponent) { | |
| 192 checkNum(x); | |
| 193 checkNum(exponent); | |
| 194 return JS('num', r'Math.pow(#, #)', x, exponent); | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 * Converts [x] to a double and returns the sine of the value. | |
| 199 * | |
| 200 * If [x] is not a finite number, the result is NaN. | |
| 201 */ | |
| 202 double sin(num x) | |
| 203 => JS('double', r'Math.sin(#)', checkNum(x)); | |
| 204 | |
| 205 /** | |
| 206 * Converts [x] to a double and returns the cosine of the value. | |
| 207 * | |
| 208 * If [x] is not a finite number, the result is NaN. | |
| 209 */ | |
| 210 double cos(num x) | |
| 211 => JS('double', r'Math.cos(#)', checkNum(x)); | |
| 212 | |
| 213 /** | |
| 214 * Converts [x] to a double and returns the tangent of the value. | |
| 215 * | |
| 216 * The tangent function is equivalent to [:sin(x)/cos(x):] and may be | |
| 217 * infinite (positive or negative) when [:cos(x):] is equal to zero. | |
| 218 * If [x] is not a finite number, the result is NaN. | |
| 219 */ | |
| 220 double tan(num x) | |
| 221 => JS('double', r'Math.tan(#)', checkNum(x)); | |
| 222 | |
| 223 /** | |
| 224 * Converts [x] to a double and returns the arc cosine of the value. | |
| 225 * | |
| 226 * Returns a value in the range -PI..PI, or NaN if [x] is outside | |
| 227 * the range -1..1. | |
| 228 */ | |
| 229 double acos(num x) | |
| 230 => JS('double', r'Math.acos(#)', checkNum(x)); | |
| 231 | |
| 232 /** | |
| 233 * Converts [x] to a double and returns the arc sine of the value. | |
| 234 * Returns a value in the range -PI..PI, or NaN if [x] is outside | |
| 235 * the range -1..1. | |
| 236 */ | |
| 237 double asin(num x) | |
| 238 => JS('double', r'Math.asin(#)', checkNum(x)); | |
| 239 | |
| 240 /** | |
| 241 * Converts [x] to a dobule and returns the arc tangent of the vlaue. | |
| 242 * Returns a value in the range -PI/2..PI/2, or NaN if [x] is NaN. | |
| 243 */ | |
| 244 double atan(num x) | |
| 245 => JS('double', r'Math.atan(#)', checkNum(x)); | |
| 246 | |
| 247 /** | |
| 248 * Converts [x] to a double and returns the positive square root of the value. | |
| 249 * | |
| 250 * Returns -0.0 if [x] is -0.0, and NaN if [x] is otherwise negative or NaN. | |
| 251 */ | |
| 252 double sqrt(num x) | |
| 253 => JS('double', r'Math.sqrt(#)', checkNum(x)); | |
| 254 | |
| 255 /** | |
| 256 * Converts [x] to a double and returns the natural exponent, [E], | |
| 257 * to the power [x]. | |
| 258 * Returns NaN if [x] is NaN. | |
| 259 */ | |
| 260 double exp(num x) | |
| 261 => JS('double', r'Math.exp(#)', checkNum(x)); | |
| 262 | |
| 263 /** | |
| 264 * Converts [x] to a double and returns the natural logarithm of the value. | |
| 265 * Returns negative infinity if [x] is equal to zero. | |
| 266 * Returns NaN if [x] is NaN or less than zero. | |
| 267 */ | |
| 268 double log(num x) | |
| 269 => JS('double', r'Math.log(#)', checkNum(x)); | |
| 270 | |
| 271 const int _POW2_32 = 0x100000000; | |
| 272 class _JSRandom implements Random { | |
| 273 // The Dart2JS implementation of Random doesn't use a seed. | |
| 274 const _JSRandom(); | |
| 275 | |
| 276 int nextInt(int max) { | |
| 277 if (max <= 0 || max > _POW2_32) { | |
| 278 throw new RangeError("max must be in range 0 < max ≤ 2^32, was $max"); | |
| 279 } | |
| 280 return JS("int", "(Math.random() * #) >>> 0", max); | |
| 281 } | |
| 282 | |
| 283 /** | |
| 284 * Generates a positive random floating point value uniformly distributed on | |
| 285 * the range from 0.0, inclusive, to 1.0, exclusive. | |
| 286 */ | |
| 287 double nextDouble() => JS("double", "Math.random()"); | |
| 288 | |
| 289 /** | |
| 290 * Generates a random boolean value. | |
| 291 */ | |
| 292 bool nextBool() => JS("bool", "Math.random() < 0.5"); | |
| 293 } | |
| 294 class _Random implements Random { | |
| 295 // Constants used by the algorithm or masking. | |
| 296 static const double _POW2_53_D = 1.0 * (0x20000000000000); | |
| 297 static const double _POW2_27_D = 1.0 * (1 << 27); | |
| 298 static const int _MASK32 = 0xFFFFFFFF; | |
| 299 | |
| 300 // State comprised of two unsigned 32 bit integers. | |
| 301 int _lo = 0; | |
| 302 int _hi = 0; | |
| 303 | |
| 304 // Implements: | |
| 305 // uint64_t hash = 0; | |
| 306 // do { | |
| 307 // hash = hash * 1037 ^ mix64((uint64_t)seed); | |
| 308 // seed >>= 64; | |
| 309 // } while (seed != 0 && seed != -1); // Limits for pos/neg seed. | |
| 310 // if (hash == 0) { | |
| 311 // hash = 0x5A17; | |
| 312 // } | |
| 313 // _lo = hash & _MASK_32; | |
| 314 // _hi = hash >> 32; | |
| 315 // and then does four _nextState calls to shuffle bits around. | |
| 316 _Random(int seed) { | |
| 317 int empty_seed = 0; | |
| 318 if (seed < 0) { | |
| 319 empty_seed = -1; | |
| 320 } | |
| 321 do { | |
| 322 int low = seed & _MASK32; | |
| 323 seed = (seed - low) ~/ _POW2_32; | |
| 324 int high = seed & _MASK32; | |
| 325 seed = (seed - high) ~/ _POW2_32; | |
| 326 | |
| 327 // Thomas Wang's 64-bit mix function. | |
| 328 // http://www.concentric.net/~Ttwang/tech/inthash.htm | |
| 329 // via. http://web.archive.org/web/20071223173210/http://www.concentric.ne
t/~Ttwang/tech/inthash.htm | |
| 330 | |
| 331 // key = ~key + (key << 21); | |
| 332 int tmplow = low << 21; | |
| 333 int tmphigh = (high << 21) | (low >> 11); | |
| 334 tmplow = (~low & _MASK32) + tmplow; | |
| 335 low = tmplow & _MASK32; | |
| 336 high = (~high + tmphigh + ((tmplow - low) ~/ 0x100000000)) & _MASK32; | |
| 337 // key = key ^ (key >> 24). | |
| 338 tmphigh = high >> 24; | |
| 339 tmplow = (low >> 24) | (high << 8); | |
| 340 low ^= tmplow; | |
| 341 high ^= tmphigh; | |
| 342 // key = key * 265 | |
| 343 tmplow = low * 265; | |
| 344 low = tmplow & _MASK32; | |
| 345 high = (high * 265 + (tmplow - low) ~/ 0x100000000) & _MASK32; | |
| 346 // key = key ^ (key >> 14); | |
| 347 tmphigh = high >> 14; | |
| 348 tmplow = (low >> 14) | (high << 18); | |
| 349 low ^= tmplow; | |
| 350 high ^= tmphigh; | |
| 351 // key = key * 21 | |
| 352 tmplow = low * 21; | |
| 353 low = tmplow & _MASK32; | |
| 354 high = (high * 21 + (tmplow - low) ~/ 0x100000000) & _MASK32; | |
| 355 // key = key ^ (key >> 28). | |
| 356 tmphigh = high >> 28; | |
| 357 tmplow = (low >> 28) | (high << 4); | |
| 358 low ^= tmplow; | |
| 359 high ^= tmphigh; | |
| 360 // key = key + (key << 31); | |
| 361 tmplow = low << 31; | |
| 362 tmphigh = (high << 31) | (low >> 1); | |
| 363 tmplow += low; | |
| 364 low = tmplow & _MASK32; | |
| 365 high = (high + tmphigh + (tmplow - low) ~/ 0x100000000) & _MASK32; | |
| 366 // Mix end. | |
| 367 | |
| 368 // seed = seed * 1037 ^ key; | |
| 369 tmplow = _lo * 1037; | |
| 370 _lo = tmplow & _MASK32; | |
| 371 _hi = (_hi * 1037 + (tmplow - _lo) ~/ 0x100000000) & _MASK32; | |
| 372 _lo ^= low; | |
| 373 _hi ^= high; | |
| 374 } while (seed != empty_seed); | |
| 375 | |
| 376 if (_hi == 0 && _lo == 0) { | |
| 377 _lo = 0x5A17; | |
| 378 } | |
| 379 _nextState(); | |
| 380 _nextState(); | |
| 381 _nextState(); | |
| 382 _nextState(); | |
| 383 } | |
| 384 | |
| 385 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. | |
| 386 // http://en.wikipedia.org/wiki/Multiply-with-carry | |
| 387 // The constant A (0xFFFFDA61) is selected from "Numerical Recipes 3rd | |
| 388 // Edition" p.348 B1. | |
| 389 | |
| 390 // Implements: | |
| 391 // var state = (A * _lo + _hi) & _MASK_64; | |
| 392 // _lo = state & _MASK_32; | |
| 393 // _hi = state >> 32; | |
| 394 void _nextState() { | |
| 395 // Simulate (0xFFFFDA61 * lo + hi) without overflowing 53 bits. | |
| 396 int tmpHi = 0xFFFF0000 * _lo; // At most 48 bits of significant result. | |
| 397 int tmpHiLo = tmpHi & _MASK32; // Get the lower 32 bits. | |
| 398 int tmpHiHi = tmpHi - tmpHiLo; // And just the upper 32 bits. | |
| 399 int tmpLo = 0xDA61 * _lo; | |
| 400 int tmpLoLo = tmpLo & _MASK32; | |
| 401 int tmpLoHi = tmpLo - tmpLoLo; | |
| 402 | |
| 403 int newLo = tmpLoLo + tmpHiLo + _hi; | |
| 404 _lo = newLo & _MASK32; | |
| 405 int newLoHi = newLo - _lo; | |
| 406 _hi = ((tmpLoHi + tmpHiHi + newLoHi) ~/ _POW2_32) & _MASK32; | |
| 407 assert(_lo < _POW2_32); | |
| 408 assert(_hi < _POW2_32); | |
| 409 } | |
| 410 | |
| 411 int nextInt(int max) { | |
| 412 if (max <= 0 || max > _POW2_32) { | |
| 413 throw new RangeError("max must be in range 0 < max ≤ 2^32, was $max"); | |
| 414 } | |
| 415 if ((max & (max - 1)) == 0) { | |
| 416 // Fast case for powers of two. | |
| 417 _nextState(); | |
| 418 return _lo & (max - 1); | |
| 419 } | |
| 420 | |
| 421 int rnd32; | |
| 422 int result; | |
| 423 do { | |
| 424 _nextState(); | |
| 425 rnd32 = _lo; | |
| 426 result = rnd32.remainder(max); // % max; | |
| 427 } while ((rnd32 - result + max) >= _POW2_32); | |
| 428 return result; | |
| 429 } | |
| 430 | |
| 431 double nextDouble() { | |
| 432 _nextState(); | |
| 433 int bits26 = _lo & ((1 << 26) - 1); | |
| 434 _nextState(); | |
| 435 int bits27 = _lo & ((1 << 27) - 1); | |
| 436 return (bits26 * _POW2_27_D + bits27) / _POW2_53_D; | |
| 437 } | |
| 438 | |
| 439 bool nextBool() { | |
| 440 _nextState(); | |
| 441 return (_lo & 1) == 0; | |
| 442 } | |
| 443 } | |
| OLD | NEW |