• 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 std.core;
17
18/**
19 * Represents boxed double value and related operations
20 */
21export final class Double extends Floating implements Comparable<Double>, JSONable<Double> {
22    private value: double;
23
24    /**
25     * Constructs a new Double instance with initial value zero
26     *
27     */
28    public constructor() {
29        this.value = 0.0;
30    }
31
32    /**
33     * Constructs a new Double instance with provided initial value
34     *
35     * @param value the initial value
36     *
37     */
38    public constructor(value: double) {
39        this.value = value;
40    }
41
42    /**
43     * Constructs a new Double instance with provided initial value
44     *
45     * @param value the initial value
46     *
47     */
48    public constructor(value: Double) {
49        this.value = value.doubleValue();
50    }
51
52    /**
53     * Constructs a new Double instance from string
54     *
55     * @param value string that may contain a number
56     */
57    public constructor(value: String) {
58        this.value = Double.numberFromString(value);
59    }
60
61    public constructor(value: BigInt) {
62        this.value = value.doubleValue()
63    }
64
65    /**
66     * Creates a new instance of a Double
67     *
68     * @returns A new Double instance
69     */
70    static invoke(): number {
71        return new Double();
72    }
73
74    /**
75     * Creates a new instance of a Double
76     *
77     * @param value The value to be converted to a number. Can be a string, number, or BigInt (optional).
78     *
79     * @returns A new Double instance
80     */
81    static invoke(value: String | Number | BigInt | undefined): number {
82        if (value instanceof String) {
83            return new Double(value as String);
84        } else if (value instanceof Number) {
85            return new Double(value as Number);
86        } else if (value instanceof BigInt) {
87            return new Double(value as BigInt);
88        }
89        return new Double(NaN);
90    }
91
92    /**
93     * Returns value of this instance as a primitive
94     *
95     * @returns value of this instance
96     * @tag arkts
97     */
98    public unboxed(): double {
99        return this.value;
100    }
101
102    /**
103     * Returns boxed representation of the primitive
104     *
105     * @param value value to box
106     *
107     * @returns boxed value
108     * @tag arkts
109     */
110    public static valueOf(value: double): Double {
111        // TODO(ivan-tyulyandin): caching is possible
112        return new Double(value);
113    }
114
115    /**
116     * Returns boxed representation of the primitive
117     *
118     * @param value value to box
119     *
120     * @returns boxed value
121     */
122    public valueOf(): number {
123        return this.value as number;
124    }
125
126    /**
127     * Minimal value that this type can have as a double
128     * the workarond for libc's double literal parsing bug
129     *
130     */
131    public static readonly MIN_VALUE: double = 4.9e-300 / 1.e+24;
132
133    /**
134     * Maximal value that this type can have as a double
135     *
136     */
137    public static readonly MAX_VALUE: double = 1.7976931348623157e+308;
138
139    /**
140     * Maximal integer value that can be used as a double without loss of precision
141     *
142     */
143    public static readonly MAX_SAFE_INTEGER: double = 9007199254740991;
144
145    /**
146     * Minimal integer value that can be used as a double without loss of precision
147     *
148     */
149    public static readonly MIN_SAFE_INTEGER: double = -9007199254740991;
150
151    /**
152     * Size of this type in bits
153     * @tag arkts
154     */
155    public static readonly BIT_SIZE: byte = 64;
156
157    /**
158     * Size of this type in bytes
159     * @tag arkts
160     */
161    public static readonly BYTE_SIZE: byte = 8;
162
163    /**
164     * Represents the NaN value according to IEEE-754 specification
165     *
166     */
167    public static readonly NaN: double = 0.0 / 0.0;
168
169    /**
170     * Represents the +Infinity value according to IEEE-754 specification
171     *
172     */
173    public static readonly POSITIVE_INFINITY: double = 1.0 / 0.0;
174
175    /**
176     * Represents the -Infinity value according to IEEE-754 specification
177     *
178     */
179    public static readonly NEGATIVE_INFINITY: double = -1.0 / 0.0;
180
181    /**
182     * Number of significant precision bits in this floating type
183     * @tag arkts
184     */
185    public static readonly PRECISION: byte = 53;
186
187    /**
188     * Minimal possible difference between two double values.
189     * For double (IEEE-754 binary64) it is 2^(-52) and its bit representation is 0x3cb0000000000000.
190     * @tag arkts
191     */
192    public static readonly DELTA: double = Double.bitCastFromLong(0x3cb0000000000000);
193
194    /**
195     * Minimal possible difference between two double values
196     *
197     */
198    public static readonly EPSILON: double = Double.DELTA;
199
200
201    /**
202     * Returns value of this instance
203     *
204     * @returns value as byte
205     * @tag arkts
206     */
207    public override byteValue(): byte {
208        return this.value as byte;
209    }
210
211    /**
212     * Returns value of this instance
213     *
214     * @returns value as short
215     * @tag arkts
216     */
217    public override shortValue(): short {
218        return this.value as short;
219    }
220
221    /**
222     * Returns value of this instance
223     *
224     * @returns value as int
225     * @tag arkts
226     */
227    public override intValue(): int {
228        return this.value as int;
229    }
230
231    /**
232     * Returns value of this instance
233     *
234     * @returns value as long
235     * @tag arkts
236     */
237    public override longValue(): long {
238        return this.value as long;
239    }
240
241    /**
242     * Returns value of this instance
243     *
244     * @returns value as float
245     * @tag arkts
246     */
247    public override floatValue(): float {
248        return this.value as float;
249    }
250
251    /**
252     * Returns value of this instance
253     *
254     * @returns value as double
255     * @tag arkts
256     */
257    public override doubleValue(): double {
258        return this.value;
259    }
260
261    /**
262     * Compares this instance to other Double object
263     * The result is less than 0 if this instance lesser than provided object
264     * 0 if they are equal
265     * and greater than 0 otherwise.
266     *
267     * @param other Double object to compare with
268     *
269     * @returns result of the comparison
270     * @tag arkts
271     */
272    public override compareTo(other: Double): int {
273        return (this.value - other.unboxed()) as int;
274    }
275
276    /**
277     * toString(d: double, r: int): String -- returns a string representation of d by radix r
278     * @tag arkts
279     */
280    public static native toString(d: double, r: int): String;
281
282    /**
283     * @tag arkts
284     */
285    public static toString(d: double): String {
286        return Double.toString(d, 10);
287    }
288
289    /**
290     * @tag arkts
291     */
292    public toString(r: int): String {
293        return Double.toString(this.value, r);
294    }
295
296    /**
297     * Converts this object to a string
298     *
299     * @returns result of the conversion
300     *
301     */
302    public override toString(): String {
303        return Double.toString(this.value, 10);
304    }
305
306    /**
307     * Accepts a locale and returns string in language-sensitive representation
308     *
309     * @remark
310     * Implemented as native function,  @see `toLocaleString()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#741).
311     * @returns result of the conversion in a local representation
312     *
313     */
314    public native toLocaleString(locale: String): String;
315
316    /**
317     * Without an argument method returns just toString value
318     *
319     * @returns result of the conversion
320     *
321     */
322    public toLocaleString(): String {
323        return this.toLocaleString("")
324    }
325
326    /**
327     * Returns a hash code (integer representation) for this instance
328     *
329     * @returns representation of this instance
330     * @tag arkts
331     */
332    public override $_hashCode(): int {
333        return this.intValue();
334    }
335
336    /**
337     * compare(double, double) checks if two doubles are differs no more than by Double.DELTA
338     *
339     * @param lhs left-hand side double for comparison
340     *
341     * @param rhs right-hand side double for comparison
342     *
343     * @returns true if lhs and rhs are equal with respect to Double.DELTA
344     * @tag arkts
345     */
346    public static compare(lhs: double, rhs: double): boolean {
347        return (abs(lhs - rhs) <= Double.DELTA)
348    }
349
350    /**
351    * Checks for equality this instance with provided object, treated as a Double
352    *
353    * @param other object to be checked against
354    *
355    * @returns true if provided object and this instance have same value, false otherwise
356    * Returns false if type of provided object is not the same as this type
357    * @tag arkts
358    */
359    public equals(other: NullishType): boolean {
360        if (__runtimeIsSameReference(this, other)) {
361            return true
362        }
363
364        if (!(other instanceof Double)) {
365            return false
366        }
367
368        return this.value == (other as Double).value
369    }
370
371    /**
372     * isNaN(double) checks if double is NaN (not a number)
373     *
374     * @param v the double to test
375     *
376     * @returns true if the argument is NaN
377     *
378     */
379    public static isNaN(v: double): boolean {
380        // IEEE-754 feature
381        return v != v;
382    }
383
384    /**
385     * isNaN() checks if the underlying double is NaN (not a number)
386     *
387     * @returns true if the underlying double is NaN
388     * @tag arkts
389     */
390    public isNaN(): boolean {
391        return Double.isNaN(this.value);
392    }
393
394    /**
395     * isFinite(double) checks if double is a floating point value (not a NaN or infinity)
396     *
397     * @param v the double to test
398     *
399     * @returns true if the argument is a floating point value
400     *
401     */
402    public static isFinite(v: double): boolean {
403        return !(Double.isNaN(v) || (v == Double.POSITIVE_INFINITY) || (v == Double.NEGATIVE_INFINITY));
404    }
405
406    /**
407     * isFinite() checks if the underlying double is a floating point value (not a NaN or infinity)
408     *
409     * @returns true if the underlying double is a floating point value
410     * @tag arkts
411     */
412    public isFinite(): boolean {
413        return Double.isFinite(this.value);
414    }
415
416    /**
417     * Checks if double is similar to an integer value
418     *
419     * @param v the double to test
420     *
421     * @returns true if the argument is similar to an integer value
422     *
423     */
424    public static isInteger(v: double): boolean {
425        // In the language % works as C fmod that differs with IEEE-754 % definition
426        return Double.compare(v % (1.0 as double), 0.0 as double);
427    }
428
429    /**
430     * Checks if the underlying double is similar to an integer value
431     *
432     * @returns true if the underlying double is similar to an integer value
433     * @tag arkts
434     */
435    public isInteger(): boolean {
436        return Double.isInteger(this.value);
437    }
438
439    /**
440     * Checks if double is a safe integer value
441     *
442     * @param v the double to test
443     *
444     * @returns true if the argument is integer ans less than MAX_SAFE_INTEGER
445     *
446     */
447    public static isSafeInteger(v: double): boolean {
448        return Double.isInteger(v) && (abs(v) <= Double.MAX_SAFE_INTEGER);
449    }
450
451    /**
452     * Checks if double is a safe integer value
453     *
454     * @returns true if the underlying double is a safe integer
455     * @tag arkts
456     */
457    public isSafeInteger(): boolean {
458        return Double.isSafeInteger(this.value);
459    }
460
461
462    /**
463     * Performs floating point addition of this instance with provided one, returns the result as new instance
464     *
465     * @param other Right hand side of the addition
466     *
467     * @returns Result of the addition
468     * @tag arkts
469     */
470    public add(other: Double): Double {
471        return Double.valueOf((this.value + other.doubleValue()) as double)
472    }
473
474    /**
475     * Performs floating point subtraction of this instance with provided one, returns the result as new instance
476     *
477     * @param other Right hand side of the subtraction
478     *
479     * @returns Result of the subtraction
480     * @tag arkts
481     */
482    public sub(other: Double): Double {
483        return Double.valueOf((this.value - other.doubleValue()) as double)
484    }
485
486    /**
487     * Performs floating point multiplication of this instance with provided one, returns the result as new instance
488     *
489     * @param other Right hand side of the multiplication
490     *
491     * @returns Result of the multiplication
492     * @tag arkts
493     */
494    public mul(other: Double): Double {
495        return Double.valueOf((this.value * other.doubleValue()) as double)
496    }
497
498    /**
499     * Performs floating point division of this instance with provided one, returns the result as new instance
500     *
501     * @param other Right hand side of the division
502     *
503     * @returns Result of the division
504     * @tag arkts
505     */
506    public div(other: Double): Double {
507        return Double.valueOf((this.value / other.doubleValue()) as double)
508    }
509
510    /**
511     * Checks if this instance value is less than value of provided instance
512     *
513     * @param other Right hand side of the comparison
514     *
515     * @returns true if this value is less than provided, false otherwise
516     * @tag arkts
517     */
518    public isLessThan(other: Double): boolean {
519        return this.value < other.doubleValue();
520    }
521
522    /**
523     * Checks if this instance value is less than or equal to value of provided instance
524     *
525     * @param other Right hand side of the comparison
526     *
527     * @returns true if this value is less than or equal to provided, false otherwise
528     * @tag arkts
529     */
530    public isLessEqualThan(other: Double): boolean {
531        return this.value <= other.doubleValue();
532    }
533
534    /**
535     * Checks if this instance value is greater than value of provided instance
536     *
537     * @param other Right hand side of the comparison
538     *
539     * @returns true if this value is greater than provided, false otherwise
540     * @tag arkts
541     */
542    public isGreaterThan(other: Double): boolean {
543        return this.value > other.doubleValue();
544    }
545
546    /**
547     * Checks if this instance value is greater than or equal to value of provided instance
548     *
549     * @param other Right hand side of the comparison
550     *
551     * @returns true if this value is greater than or equal to provided, false otherwise
552     * @tag arkts
553     */
554    public isGreaterEqualThan(other: Double): boolean {
555        return this.value >= other.doubleValue();
556    }
557
558    /**
559     * parseFloat(String) converts std.core.String to double
560     *
561     * @param s the string to convert
562     *
563     * @returns the result of conversion
564     *
565     * @note
566     * If arg is "+Infinity", "Infinity" or "-Infinity", return value is `inf` or `-inf` respectively.
567     * If arg is "+0" or "-0", return value is 0 or -0.
568     * If arg has leading zeroes, it's ignored: "0001.5" -> 1.5, "-0001.5" -> -1.5
569     * If arg starts from ".", leading zero is implied: ".5" -> 0.5, "-.5" -> -0.5
570     * If arg successfully parsed, trailing non-digits ignored: "-.6ffg" -> -0.6
571     * If arg can not be parsed into a number, NaN is returned
572     *
573     * @remark
574     * Implemented as native function,  @see `parseFloat()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#653).
575     *
576     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parsefloat
577     *
578    */
579    public static native parseFloat(s: String): double;
580
581    /**
582     * parseInt(String, int) parses from String an integer of specified radix
583     *
584     * @param s the string to convert
585     * @param r the radix of conversion; should be [2, 36]; 0 assumed to be 10
586     *
587     * @returns the result of parsing
588     *
589     * @note
590     * If args ("10", 1) -> thrown ArgumentOutOfRangeException, ("10", 37) -> thrown ArgumentOutOfRangeException
591     * If args ("10", 2) -> 2
592     * If args ("10", 10) -> 10, ("10", 0) -> 10
593     * If args ("ff", 16) -> 255
594     * etc.
595     *
596     * @remark
597     * Implemented as native function,  @see `parseInt()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#663).
598     *
599     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parseint
600     *
601    */
602    public static native parseIntCore(s: String, r: int): double;
603
604    /**
605     * parseInt(String, int) parses from String an integer of specified radix
606     *
607     * @param s the string to convert
608     * @param r the radix of conversion; should be [2, 36]; 0 assumed to be 10
609     *
610     * @returns the result of parsing
611     *
612     * @note
613     * If args ("10", 1) -> thrown ArgumentOutOfRangeException, ("10", 37) -> thrown ArgumentOutOfRangeException
614     * If args ("10", 2) -> 2
615     * If args ("10", 10) -> 10, ("10", 0) -> 10
616     * If args ("ff", 16) -> 255
617     * etc.
618     *
619     * @remark
620     * Implemented as native function,  @see `parseInt()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#663).
621     *
622     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parseint
623     *
624    */
625    public static parseInt(s: String, r: double): double {
626        if ((r < 2.0 || r > 36.0) && r != 0.0) {
627            return NaN;
628        } else {
629            return Double.parseIntCore(s, r as int);
630        }
631    }
632
633    /**
634     * parseInt(String, int) parses from String an integer of specified radix
635     *
636     * @param s the string to convert
637     * @param r the radix of conversion; should be [2, 36]; 0 assumed to be 10
638     *
639     * @returns the result of parsing
640     *
641     * @note
642     * If args ("10", 1) -> thrown ArgumentOutOfRangeException, ("10", 37) -> thrown ArgumentOutOfRangeException
643     * If args ("10", 2) -> 2
644     * If args ("10", 10) -> 10, ("10", 0) -> 10
645     * If args ("ff", 16) -> 255
646     * etc.
647     *
648     * @remark
649     * Implemented as native function,  @see `parseInt()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#663).
650     *
651     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.parseint
652     *
653    */
654    public static parseInt(s: String, r: int): double {
655        if ((r < 2 || r > 36) && r != 0.0) {
656            return NaN;
657        } else {
658            return Double.parseIntCore(s, r);
659        }
660    }
661
662    /**
663     * parseInt(String) parses from String an integer of radix 10
664     *
665     * @param s the string to convert
666     *
667     * @returns the result of parsing
668     *
669    */
670    public static parseInt(s: String): double {
671        return Double.parseIntCore(s, -1 as int);
672    }
673
674    /**
675     * toExponential(double) returns std.core.String representing the underlying double in exponential notation
676     *
677     * @param d the exponent (rounded to nearest integer); must be in [0, 100]
678     *
679     * @returns the result of conversion
680     *
681     * @note
682     * If d = new Double(0.25); d.toExponential(2) -> "2.50e-1"
683     * If d = new Double(0.25); d.toExponential(2.5) -> "2.50e-1"
684     * If d = new Double(0.25); d.toExponential(1) -> "2.5e-1"
685     * If d = new Double(12345.01); d.toExponential(10) -> "1.2345010000e+4"
686     * If d = new Double(NaN); d.toExponential(10) -> "NaN";
687     * If d = new Double(Double.POSITIVE_INFINITY); d.toExponential(10) -> "Infinity";
688     *                                                                     "-Infinity" for negative
689     *
690     * @remark
691     * Implemented as native function,  @see `toExponential()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#673).
692     *
693     * ECMA reference: https://tc39.es/ecma262/multipage/doubles-and-dates.html#sec-double.prototype.toexponential
694     *
695    */
696    public native toExponential(d: double): String;
697
698    /**
699     * toExponential() returns std.core.String representing the underlying double in exponential notation
700     *
701     * @returns the result of conversion
702     *
703    */
704    public toExponential(): String {
705        return this.toExponential(0);
706    }
707
708    /**
709     * toPrecision(double) returns std.core.String representing the underlying double on the specified precision
710     *
711     * @param d precision (rounded to nearest integer); must be in [1, 100]
712     *
713     * @returns the result of conversion
714     *
715     * @note
716     * If d = new Double(0.25); d.toPrecision(4) -> "0.2500"
717     * If d = new Double(1.01); d.toPrecision(4.7) -> "1.010"
718     * If d = new Double(0.25); d.toPrecision(0) -> thrown ArgumentOutOfRangeException
719     * If d = new Double(12345.123455); d.toPrecision(10) -> "12345.12346"
720     *
721     * @remark
722     * Implemented as native function,  @see `toPrecision()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#683).
723     *
724     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.toprecision
725     *
726    */
727    public native toPrecision(d: double): String;
728
729    /**
730     * toPrecision() returns std.core.String representing the underlying double in exponential notation
731     *                       basically, if toPrecision called with no argument it's just toString according
732     *                       to spec
733     *
734     * @returns the result of conversion
735     *
736    */
737    public toPrecision(): String {
738        return this.toString();
739    }
740
741    /**
742     * toFixed(double) returns std.core.String representing the underlying double using fixed-point notation
743     *
744     * @param d fixed size (integer part); must be in [0, 100]
745     *
746     * @returns the result of conversion
747     *
748     * @note
749     * If d = new Double(0.1); d.toFixed(0) -> "0"
750     * If d = new Double(0.7); d.toFixed(0) -> "1"
751     * If d = new Double(0.12345); d.toFixed(1) -> "0.1"
752     * If d = new Double(0.12345); d.toFixed(3) -> "0.123"
753     * If d = new Double(Double.POSITIVE_INFINITY); d.toFixed(3) -> "Infinity"
754     * If d = new Double(Double.NaN); d.toFixed(3) -> "NaN"
755     * If d = new Double(0.25); d.toFixed(200) -> thrown ArgumentOutOfRangeException
756     *
757     * @remark
758     * Implemented as native function,  @see `toFixed()` intrinsic [declaration](https://gitee.com/openharmony-sig/arkcompiler_runtime_core/blob/master/plugins/ets/runtime/ets_libbase_runtime.yaml#693).
759     *
760     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.prototype.tofixed
761     *
762    */
763    public native toFixed(d: double): String;
764
765    /**
766     * toFixed(double) returns std.core.String representing the underlying double using fixed-point notation
767     *
768     * @returns the result of conversion
769     *
770    */
771    public toFixed(): String {
772        return this.toFixed(0);
773    }
774
775    /**
776     * Converts bit representation to corresponding IEEE-754 floating point representation
777     * @param bits bits to convert
778     *
779     * @returns double - converted value
780     * @tag arkts
781     */
782    public static native bitCastFromLong(bits: long): double
783
784    /**
785     * Converts IEEE-754 floating point representation to corresponding bit representation
786     * @param val value to convert
787     *
788     * @returns long - bit representation
789     * @tag arkts
790     */
791    public static native bitCastToLong(val: double): long
792
793    /**
794     * Creates a Double instance based on JSONValue
795     *
796     * @param json: JSONValue - a JSON representation
797     *
798     * @throws JSONTypeError if json does not encode a valid double
799     *
800     * @returns Double - double value decoded from JSON
801     * @tag arkts
802     */
803    static createFromJSONValue(json: JSONValue): Double {
804        if (json instanceof JSONNumber) {
805            return Double.valueOf((json as JSONNumber).value)
806        }
807        throw new JSONTypeError("Cannot create Double from JSON", new ErrorOptions(json as Object))
808    }
809
810
811    /**
812     * numberFromString(String) converts std.core.String to double
813     *
814     * @param s the string to convert
815     *
816     * @returns the result of conversion
817     *
818     * @note
819     * If arg is "+Infinity", "Infinity" or "-Infinity", return value is `inf` or `-inf` respectively.
820     * If arg is "+0" or "-0", return value is 0 or -0.
821     * If arg has leading zeroes, it's ignored: "0001.5" -> 1.5, "-0001.5" -> -1.5
822     * If arg starts from ".", leading zero is implied: ".5" -> 0.5, "-.5" -> -0.5
823     * If arg successfully parsed, trailing non-digits cause return value is NaN: "-.6ffg" -> -NaN
824     * If arg can not be parsed into a number, NaN is returned
825     *
826     *
827     * ECMA reference: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number-constructor-number-value
828     */
829    private static native numberFromString(s: String): double;
830}
831