@@ -474,7 +474,7 @@ export function itoa64(value: i64, radix: i32): String {
474
474
@lazy let _frc_minus : u64 = 0 ;
475
475
476
476
// @ts -ignore: decorator
477
- @lazy let _frc_plus : u64 = 0 ;
477
+ @lazy let _frc_plus : u64 = 0 ;
478
478
479
479
// @ts -ignore: decorator
480
480
@lazy let _frc_pow : u64 = 0 ;
@@ -511,14 +511,14 @@ function umul64e(e1: i32, e2: i32): i32 {
511
511
512
512
// @ts -ignore: decorator
513
513
@inline
514
- function normalizedBoundaries ( f : u64 , e : i32 ) : void {
514
+ function normalizedBoundaries ( f : u64 , e : i32 , isSingle : bool ) : void {
515
515
let frc = ( f << 1 ) + 1 ;
516
516
let exp = e - 1 ;
517
517
let off = < i32 > clz < u64 > ( frc ) ;
518
518
frc <<= off ;
519
519
exp -= off ;
520
520
521
- let m = 1 + i32 ( f == 0x0010000000000000 ) ;
521
+ let m = 1 + i32 ( f == ( isSingle ? 0x00800000 : 0x0010000000000000 ) ) ;
522
522
523
523
_frc_plus = frc ;
524
524
_frc_minus = ( ( f << m ) - 1 ) << e - m - exp ;
@@ -559,16 +559,26 @@ function getCachedPower(minExp: i32): void {
559
559
560
560
// @ts -ignore: decorator
561
561
@inline
562
- function grisu2 ( value : f64 , buffer : usize , sign : i32 ) : i32 {
562
+ function grisu2 ( value : f64 , buffer : usize , sign : i32 , isSingle : bool ) : i32 {
563
+ let frc : u64 ;
564
+ let exp : i32 ;
563
565
564
566
// frexp routine
565
- let uv = reinterpret < u64 > ( value ) ;
566
- let exp = i32 ( ( uv & 0x7FF0000000000000 ) >>> 52 ) ;
567
- let sid = uv & 0x000FFFFFFFFFFFFF ;
568
- let frc = ( u64 ( exp != 0 ) << 52 ) + sid ;
569
- exp = select < i32 > ( exp , 1 , exp ) - ( 0x3FF + 52 ) ;
567
+ if ( isSingle ) {
568
+ let uv = reinterpret < u32 > ( < f32 > value ) ;
569
+ exp = ( uv & 0x7F800000 ) >>> 23 ;
570
+ let sid = uv & 0x007FFFFF ;
571
+ frc = ( u64 ( exp != 0 ) << 23 ) + sid ;
572
+ exp = ( exp || 1 ) - ( 0x7F + 23 ) ;
573
+ } else {
574
+ let uv = reinterpret < u64 > ( value ) ;
575
+ exp = i32 ( ( uv & 0x7FF0000000000000 ) >>> 52 ) ;
576
+ let sid = uv & 0x000FFFFFFFFFFFFF ;
577
+ frc = ( u64 ( exp != 0 ) << 52 ) + sid ;
578
+ exp = ( exp || 1 ) - ( 0x3FF + 52 ) ;
579
+ }
570
580
571
- normalizedBoundaries ( frc , exp ) ;
581
+ normalizedBoundaries ( frc , exp , isSingle ) ;
572
582
getCachedPower ( _exp ) ;
573
583
574
584
// normalize
@@ -716,28 +726,35 @@ function prettify(buffer: usize, length: i32, k: i32): i32 {
716
726
}
717
727
}
718
728
719
- function dtoa_core ( buffer : usize , value : f64 ) : i32 {
729
+ function dtoa_core ( buffer : usize , value : f64 , isSingle : bool ) : i32 {
720
730
let sign = i32 ( value < 0 ) ;
721
731
if ( sign ) {
722
732
value = - value ;
723
733
store < u16 > ( buffer , CharCode . MINUS ) ;
724
734
}
725
- // assert(value > 0 && value <= 1.7976931348623157e308 );
726
- let len = grisu2 ( value , buffer , sign ) ;
735
+ // assert(value > 0 && value <= (isSingle ? f32.MAX_VALUE : f64.MAX_VALUE) );
736
+ let len = grisu2 ( value , buffer , sign , isSingle ) ;
727
737
len = prettify ( buffer + ( sign << 1 ) , len - sign , _K ) ;
728
738
return len + sign ;
729
739
}
730
740
731
741
// @ts -ignore: decorator
732
742
@lazy @inline const dtoa_buf = memory . data ( MAX_DOUBLE_LENGTH << 1 ) ;
733
743
734
- export function dtoa ( value : f64 ) : String {
744
+ export function dtoa < T extends number > ( value : T ) : String {
745
+ const isSingle = isFloat < T > ( ) && sizeof < T > ( ) == 4 ;
746
+ return dtoa_impl ( value , isSingle ) ;
747
+ }
748
+
749
+ // @ts -ignore: decorator
750
+ @inline
751
+ function dtoa_impl ( value : f64 , isSingle : bool ) : String {
735
752
if ( value == 0 ) return "0.0" ;
736
753
if ( ! isFinite ( value ) ) {
737
754
if ( isNaN ( value ) ) return "NaN" ;
738
755
return select < String > ( "-Infinity" , "Infinity" , value < 0 ) ;
739
756
}
740
- let size = dtoa_core ( dtoa_buf , value ) << 1 ;
757
+ let size = dtoa_core ( dtoa_buf , value , isSingle ) << 1 ;
741
758
let result = changetype < String > ( __new ( size , idof < String > ( ) ) ) ;
742
759
memory . copy ( changetype < usize > ( result ) , dtoa_buf , size ) ;
743
760
return result ;
@@ -821,7 +838,14 @@ export function itoa_buffered<T extends number>(buffer: usize, value: T): u32 {
821
838
return sign + decimals ;
822
839
}
823
840
824
- export function dtoa_buffered ( buffer : usize , value : f64 ) : u32 {
841
+ export function dtoa_buffered < T extends number > ( buffer : usize , value : T ) : u32 {
842
+ const isSingle = isFloat < T > ( ) && sizeof < T > ( ) == 4 ;
843
+ return dtoa_buffered_impl ( buffer , value , isSingle ) ;
844
+ }
845
+
846
+ // @ts -ignore: decorator
847
+ @inline
848
+ function dtoa_buffered_impl ( buffer : usize , value : f64 , isSingle : bool ) : u32 {
825
849
if ( value == 0 ) {
826
850
store < u16 > ( buffer , CharCode . _0 ) ;
827
851
store < u16 > ( buffer , CharCode . DOT , 2 ) ;
@@ -845,5 +869,5 @@ export function dtoa_buffered(buffer: usize, value: f64): u32 {
845
869
return 8 + u32 ( sign ) ;
846
870
}
847
871
}
848
- return dtoa_core ( buffer , value ) ;
872
+ return dtoa_core ( buffer , value , isSingle ) ;
849
873
}
0 commit comments