1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package escompat; 17 18import {PI, E, LN10, LN2, LOG2E, LOG10E, SQRT1_2, SQRT2} from "std/math/consts"; 19 20/** 21 * The Math class contains static properties and methods for mathematical constants and functions. 22 */ 23export class Math { 24 // TODO(dmitrys99) Reuse constants from "std/math" 25 /** 26 * PI as double value 27 */ 28 public static readonly PI: number = PI; 29 30 /** 31 * Euler number as double value 32 */ 33 public static readonly E: number = E; 34 35 /** 36 * Natural logarithm of 10 as double value 37 */ 38 public static readonly LN10: number = LN10; 39 40 /** 41 * Natural logarithm of 2 as double value 42 */ 43 public static readonly LN2: number = LN2; 44 45 /** 46 * Logarithm base 2 of Euler number as double value 47 */ 48 public static readonly LOG2E: number = LOG2E; 49 50 /** 51 * Logarithm base 10 of Euler number as double value 52 */ 53 public static readonly LOG10E: number = LOG10E; 54 55 /** 56 * Square root of 1/2 as double value 57 */ 58 public static readonly SQRT1_2: number = SQRT1_2; 59 60 /** 61 * Square root of 2 as double value 62 */ 63 public static readonly SQRT2: number = SQRT2; 64 65 /** 66 * Absolute value 67 * 68 * @param v - Some number value 69 * 70 * @returns Absolute value of `v` 71 * 72 * @example 73 * ``` 74 * Math.abs(doubleNaN) = NaN 75 * Math.abs(doubleInf) = Inf 76 * Math.abs(doubleNegInf) = Inf 77 * ``` 78 */ 79 public static abs(x: number): number { 80 return abs(x); 81 } 82 83 /** 84 * Arccosine of angle `v` 85 * 86 * @param v angle in radians 87 * 88 * @returns Arccosine of angle `v` 89 * 90 * @remark 91 * Implemented as native function, @see `acos()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#???). 92 * 93 * @example 94 * ``` 95 * acos(doubleNaN) = -nan 96 * acos(doubleInf) = nan 97 * acos(doubleNegInf) = nan 98 */ 99 public static acos(x: number): number { 100 return acos(x); 101 } 102 103 /** 104 * Hyperbolic arccosine of an angle `v` 105 * 106 * @param v angle in radians 107 * 108 * @returns Hyperbolic arccosine of angle `v` 109 * 110 * @example 111 * ``` 112 * Math.acosh(doubleNaN) = -NaN 113 * Math.acosh(doubleInf) = Inf 114 * Math.acosh(doubleNegInf) = -NaN 115 * ``` 116 */ 117 public static acosh(x: number): number { 118 return acosh(x); 119 } 120 121 /** 122 * Arcsine of angle `v` 123 * 124 * @param v angle in radians 125 * 126 * @returns Arcsine of angle `v` 127 */ 128 public static asin(x: number): number { 129 return asin(x); 130 } 131 132 /** 133 * Hyperbolic arcsine of angle `v` 134 * 135 * @param v angle in radians 136 * 137 * @returns Hyperbolic arcsine of angle `v` 138 * 139 * @example 140 * ``` 141 * Math.asinh(doubleNaN) = -NaN 142 * Math.asinh(doubleInf) = Inf 143 * Math.asinh(doubleNegInf) = -Inf 144 * ``` 145 */ 146 public static asinh(x: number): number { 147 return asinh(x); 148 } 149 150 /** 151 * Arctangent of angle `v` 152 * 153 * @param v angle in radians 154 * 155 * @returns Arctangent of angle `v` 156 * 157 * @example 158 * ``` 159 * Math.atan(doubleNaN) = -NaN 160 * Math.atan(doubleInf) = 1.5708 161 * Math.atan(doubleNegInf) = -1.5708 162 * ``` 163 */ 164 public static atan(x: number): number { 165 return atan(x); 166 } 167 168 /** 169 * Method returns the angle in the plane (in radians) between the positive x-axis and the ray from (0, 0) to the point (x, y), for Math.atan2(y, x). 170 * 171 * @returns The angle in radians (between -π and π, inclusive) between the positive x-axis and the ray from (0, 0) to the point (x, y). 172 * 173 * @remark 174 * The atan2() method measures the counterclockwise angle θ, in radians, between the positive x-axis and the point (x, y). 175 * Note that the arguments to this function pass the y-coordinate first and the x-coordinate second. 176 */ 177 public static atan2(y: number, x: number): number { 178 return atan2(y, x); 179 } 180 181 /** 182 * Hyperbolic arctangent of angle `v` 183 * 184 * @param v angle in radians 185 * 186 * @returns Hyperbolic arctangent of angle `v` 187 * 188 * @example 189 * ``` 190 * Math.atanh(doubleNaN) = -NaN 191 * Math.atanh(doubleInf) = -NaN 192 * Math.atanh(doubleNegInf) = -NaN 193 * ``` 194 */ 195 public static atanh(x: number): number { 196 return atanh(x); 197 } 198 199 /** 200 * Cube root of a number. 201 * 202 * @param x arbitrary number 203 * 204 * @remark 205 * Math.brt() = ∛x = the unique y such that y³ = x. 206 */ 207 public static cbrt(x: number): number { 208 if (isNaN(x) || x == Infinity || x == -Infinity) return x; 209 return cbrt(x); 210 } 211 212 /** 213 * Smallest integer greater or equal to `v` 214 * 215 * @param v arbitrary number 216 * 217 * @returns Smallest integer greater or equal to v 218 * 219 * @example 220 * ``` 221 * Math.ceil(doubleNaN) = -nan 222 * Math.ceil(doubleInf) = inf 223 * Math.ceil(doubleNegInf) = -inf 224 * ``` 225 */ 226 public static ceil(x: number): number { 227 return ceil(x); 228 } 229 230 /** 231 * Leading zero bits count in 32-bit representation of `v` 232 * 233 * @param v 32-bit integer 234 * 235 * @returns Number of leading zero bits count in bit representation of `v` 236 * 237 * @example 238 * ``` 239 * Math.clz32(0xFFFFFFFF) == 0 240 * Math.clz32(0x0000FFFF) == 16 241 * Math.clz32(0x0) == 32 242 * ``` 243 */ 244 public static clz32(x: Int): Int { 245 return new Int(clz32(x.intValue())); 246 } 247 248 /** 249 * Leading zero bits count in 32-bit representation of `v` 250 * 251 * @param v 32-bit integer 252 * 253 * @returns Number of leading zero bits count in bit representation of `v` 254 * 255 * @example 256 * ``` 257 * Math.clz32(0xFFFFFFFF) == 0 258 * Math.clz32(0x0000FFFF) == 16 259 * Math.clz32(0x0) == 32 260 * ``` 261 */ 262 public static clz32(value: number): number { 263 return clz32Double(value); 264 } 265 266 /** 267 * Cosine of `x` 268 * 269 * @param x Angle in radians 270 * 271 * @returns Cosine of angle in radians 272 * 273 * @example 274 * ``` 275 * Math.cos(doubleNaN) = -NaN 276 * Math.cos(doubleInf) = -NaN 277 * Math.cos(doubleNegInf) = -NaN 278 * ``` 279 */ 280 public static cos(x: number): number { 281 return cos(x); 282 } 283 284 /** 285 * Hyperbolic cosine of an angle `x` 286 * 287 * @param x angle in radians 288 * 289 * @returns Hyperbolic cosine of angle `x` 290 * 291 * @example 292 * ``` 293 * Math.cosh(doubleNaN) = -NaN 294 * Math.cosh(doubleInf) = Inf 295 * Math.cosh(doubleNegInf) = Inf 296 * ``` 297 */ 298 public static cosh(x: number): number { 299 return cosh(x); 300 } 301 /** 302 * e raised to power `x` 303 * 304 * @param x power value 305 * 306 * @returns {@link Math.E} raised to the power of a number `x`. 307 * 308 * @example 309 * ``` 310 * Math.exp(doubleNaN) = -NaN 311 * Math.exp(doubleInf) = Inf 312 * Math.exp(doubleNegInf) = 0 313 * ``` 314 */ 315 public static exp(x: number): number { 316 return exp(x); 317 } 318 319 /** 320 * (`e` raised to power `v`) - 1 321 * 322 * @param x power value 323 * 324 * @returns {@link Math.E} raised to the power of a number `x`, subtracted by `1`. 325 * 326 * @example 327 * ``` 328 * Math.expm1(doubleNaN) = -NaN 329 * Math.expm1(doubleInf) = Inf 330 * Math.expm1(doubleNegInf) = -1 331 * ``` 332 */ 333 public static expm1(x: number): number { 334 return expm1(x); 335 } 336 337 /** 338 * Largest integer less or equal to `v` 339 * 340 * @param v arbitrary number 341 * 342 * @returns Largest integer less or equal to `v` 343 * 344 * @example 345 * ``` 346 * Math.floor(doubleNaN) = -NaN 347 * Math.floor(doubleInf) = Inf 348 * Math.floor(doubleNegInf) = -Inf 349 * ``` 350 */ 351 public static floor(x: number): number { 352 return floor(x); 353 } 354 355 /** 356 * "fround" returns nearest 32-bit single fp representation of a number 357 * in a 64-bit form 358 * 359 * Math.fround(1.337) == 1.337 // false, result would be 1.3370000123977661 360 * Math.fround(1.5) == 1.5 // true 361 * Math.fround(-5.05) == -5.05 //false, result would be -5.050000190734863 362 * Math.fround(Infinity) // Infinity 363 * Math.fround(NaN) // NaN 364 */ 365 public static fround(x: number): number { 366 return fround(x); 367 } 368 369 /** 370 * Square root of the sum of squares of `v` and `u` 371 * 372 * @param u arbitrary number 373 * @param v arbitrary number 374 * 375 * @returns The square root of the sum of squares of its arguments 376 */ 377 public static hypot(...values: number[]): number { 378 let max: number = 0; 379 let hasNaN = false; 380 381 for (const value of values) { 382 if (value == Infinity || value == -Infinity) { 383 return Infinity; 384 } 385 if (isNaN(value)) { 386 hasNaN = true; 387 } 388 max = Math.max(max, Math.abs(value)); 389 } 390 if (hasNaN) return NaN; 391 if (max == 0) return 0; 392 let sum: number = 0.0; 393 for (const value of values) { 394 let normalized = value / max; 395 sum += normalized * normalized; 396 } 397 return max * Math.sqrt(sum); 398 } 399 400 /** 401 * Method returns the result of the C-like 32-bit manipulation of the two parameters 402 * 403 * @returns (a * b) % 2 ** 32 404 * 405 * Math.imul(Infinity, 1) = 0 406 * Math.imul(NaN, 1) = 0 407 * Math.imul(2.5, 2.5) = 4 408 * Math.imul(-5, 5.05) = 25 409 * 410 */ 411 public static imul(a: number, b: number): number { 412 return imul(a, b); 413 } 414 415 416 /** 417 * Natural logarithm of `v` 418 * 419 * @param v: double - arbitrary number 420 * 421 * @returns The natural logarithm (base e) of x. If x is ±0, returns -Infinity. If x < 0, returns NaN. 422 * 423 * @example 424 * ``` 425 * Math.log(doubleNaN) = -nan 426 * Math.log(doubleInf) = inf 427 * Math.log(doubleNegInf) = -nan 428 * ``` 429 */ 430 public static log(x: number): number { 431 return log(x); 432 } 433 434 /** 435 * Base 10 logarithm of `x` 436 * 437 * @param v arbitrary number 438 * 439 * @returns The base 10 logarithm of x. If x < 0, returns NaN. 440 * 441 * @example 442 * ``` 443 * Math.log10(doubleNaN) = -NaN 444 * Math.log10(doubleInf) = Inf 445 * Math.log10(doubleNegInf) = -NaN 446 * ``` 447 */ 448 public static log10(x: number): number { 449 return log10(x); 450 } 451 452 /** 453 * Natural logarithm of (1 + `x`) 454 * 455 * @param x arbitrary number 456 * 457 * @returns The natural logarithm (base e) of x + 1. If x is -1, returns -Infinity. If x < -1, returns NaN. 458 * 459 * @example 460 * ``` 461 * Math.log1p(doubleNaN) = -NaN 462 * Math.log1p(doubleInf) = Inf 463 * Math.log1p(doubleNegInf) = -NaN 464 * ``` 465 */ 466 public static log1p(x: number): number { 467 return log1p(x); 468 } 469 470 /** 471 * Base 2 logarithm of `x` 472 * 473 * @param x arbitrary number 474 * 475 * @returns The base 2 logarithm of x. If x < 0, returns NaN. 476 * 477 * @example 478 * ``` 479 * Math.log2(doubleNaN) = -nan 480 * Math.log2(doubleInf) = inf 481 * Math.log2(doubleNegInf) = -nan 482 * ``` 483 */ 484 public static log2(x: number): number { 485 return log2(x); 486 } 487 488 /** 489 * Largest value of `u` and `v` 490 * 491 * @param u arbitrary number (of type `Int`) 492 * @param v arbitrary number (of type `Int`) 493 * 494 * @returns Largest value of `u` and `v` 495 */ 496 public static max(...values: number[]): number { 497 if (values.length == 0) { 498 return -Infinity; 499 } 500 let max = values[0]; 501 for (let i = 1; i < values.length; i++) { 502 if (isNaN(values[i])) return NaN; 503 if (values[i] > max) { 504 max = values[i]; 505 } 506 } 507 return max; 508 } 509 510 /** 511 * Smallest value of `u` and `v` 512 * 513 * @param u arbitrary number (of type `Int`) 514 * @param v arbitrary number (of type `Int`) 515 * 516 * @returns Smallest value of `u` and `v` 517 */ 518 public static min(...values: number[]): number { 519 if (values.length == 0) { 520 return Infinity; 521 } 522 let min = values[0]; 523 for (let i = 1; i < values.length; i++) { 524 if (isNaN(values[i])) return NaN; 525 if (values[i] < min) { 526 min = values[i]; 527 } 528 } 529 return min; 530 } 531 532 /** 533 * `u` raised to power of `v` 534 * 535 * @param u: base value 536 * @param v: power value 537 * 538 * @returns The value of a base `u` raised to a power `v` 539 * 540 * @example 541 * ``` 542 * Math.pow(doubleNaN, doubleInf) = -NaN 543 * Math.pow(doubleInf, doubleInf) = Inf 544 * ``` 545 */ 546 public static pow(u: number, v: number): number { 547 return power(u, v); 548 } 549 550 /** 551 * Pseudo-random number in the range [0.0, 1.0) 552 * 553 * @returns A floating-point, pseudo-random number that's greater than or equal to 0 and less than 1, 554 * with approximately uniform distribution over that range — which you can then scale to your desired range. 555 * Initial seed to the random number generator algorithm can be given using {@link seedRandom()} function. 556 * 557 */ 558 public static random(): number { 559 return random(); 560 } 561 562 /** 563 * `v` rounded to nearest integer 564 * 565 * @param v arbitrary value 566 * 567 * @returns `v` rounded to nearest integer 568 * 569 * @example 570 * ``` 571 * Math.round(doubleNaN) = -NaN 572 * Math.round(doubleInf) = Inf 573 * Math.round(doubleNegInf) = -Inf 574 * ``` 575 */ 576 public static round(x: number): number { 577 return round(x); 578 } 579 580 /** 581 * @param x arbitrary number 582 * 583 * @returns -1 if `x` is negative, 1 if `x` is positive, 0 if `x` is close to zero (epsilon is 1e-13) 584 * 585 */ 586 public static sign(x: number): number { 587 if (isNaN(x)) { 588 return x; 589 } 590 return sign(x) as double as number; 591 } 592 593 /** 594 * Sine of `v` 595 * 596 * @param v angle in radians 597 * 598 * @returns Sine of angle in radians 599 * 600 * @example 601 * ``` 602 * Math.sin(doubleNaN) = -nan 603 * Math.sin(doubleInf) = -nan 604 * Math.sin(doubleNegInf) = -nan 605 * ``` 606 */ 607 public static sin(x: number): number { 608 return sin(x); 609 } 610 611 /** 612 * Hyperbolic sine of angle `v` 613 * 614 * @param v angle in radians 615 * 616 * @returns Hyperbolic sine of angle `v` 617 * 618 * @example 619 * ``` 620 * Math.sinh(doubleNaN) = -nan 621 * Math.sinh(doubleInf) = inf 622 * Math.sinh(doubleNegInf) = -inf 623 * ``` 624 */ 625 public static sinh(x: number): number { 626 return sinh(x); 627 } 628 629 /** 630 * Square root of `x` 631 * 632 * @param x number greater or equal to zero. 633 * 634 * @returns The square root of `x`, a non-negative number. 635 * If `x` is less than zero, returns `NaN`. 636 * 637 * @example 638 * ``` 639 * Math.sqrt(doubleNaN) = -nan 640 * Math.sqrt(doubleInf) = inf 641 * Math.sqrt(doubleNegInf) = -nan 642 * ``` 643 */ 644 public static sqrt(x: number): number { 645 return sqrt(x); 646 } 647 648 /** 649 * Tangent of angle `x` 650 * 651 * @param x angle in radians 652 * 653 * @returns Tangent of angle `x` 654 * 655 * @example 656 * ``` 657 * Math.tan(doubleNaN) = -nan 658 * Math.tan(doubleInf) = -nan 659 * Math.tan(doubleNegInf) = -nan 660 * ``` 661 */ 662 public static tan(x: number): number { 663 return tan(x); 664 } 665 666 /** 667 * Hyperbolic arctangent of angle `x` 668 * 669 * @param x angle in radians 670 * 671 * @returns Hyperbolic arctangent of angle `x` 672 * 673 * @example 674 * ``` 675 * Math.atanh(doubleNaN) = -nan 676 * Math.atanh(doubleInf) = -nan 677 * Math.atanh(doubleNegInf) = -nan 678 * ``` 679 */ 680 public static tanh(x: number): number { 681 if (isNaN(x)) return NaN; 682 return tanh(x); 683 } 684 685 /** 686 * Integer part of `v` 687 * 688 * @param v number to be truncated. 689 * 690 * @returns The integer part of a number by removing any fractional digits. 691 * 692 * @notes 693 * If arg is +Infinity or -Infinity, it is returned unmodified. 694 * If arg is +0 or -0, it is returned unmodified. 695 * If arg is NaN, NaN is returned 696 * 697 */ 698 public static trunc(x: number): number { 699 return trunc(x); 700 } 701} 702