• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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