@@ -474,7 +474,7 @@ export function itoa64(value: i64, radix: i32): String {
474474@lazy let _frc_minus : u64 = 0 ;
475475
476476// @ts -ignore: decorator
477- @lazy let _frc_plus : u64 = 0 ;
477+ @lazy let _frc_plus : u64 = 0 ;
478478
479479// @ts -ignore: decorator
480480@lazy let _frc_pow : u64 = 0 ;
@@ -511,14 +511,14 @@ function umul64e(e1: i32, e2: i32): i32 {
511511
512512// @ts -ignore: decorator
513513@inline
514- function normalizedBoundaries ( f : u64 , e : i32 ) : void {
514+ function normalizedBoundaries ( f : u64 , e : i32 , isSingle : bool ) : void {
515515 let frc = ( f << 1 ) + 1 ;
516516 let exp = e - 1 ;
517517 let off = < i32 > clz < u64 > ( frc ) ;
518518 frc <<= off ;
519519 exp -= off ;
520520
521- let m = 1 + i32 ( f == 0x0010000000000000 ) ;
521+ let m = 1 + i32 ( f == ( isSingle ? 0x00800000 : 0x0010000000000000 ) ) ;
522522
523523 _frc_plus = frc ;
524524 _frc_minus = ( ( f << m ) - 1 ) << e - m - exp ;
@@ -559,16 +559,26 @@ function getCachedPower(minExp: i32): void {
559559
560560// @ts -ignore: decorator
561561@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 ;
563565
564566 // 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+ }
570580
571- normalizedBoundaries ( frc , exp ) ;
581+ normalizedBoundaries ( frc , exp , isSingle ) ;
572582 getCachedPower ( _exp ) ;
573583
574584 // normalize
@@ -716,28 +726,35 @@ function prettify(buffer: usize, length: i32, k: i32): i32 {
716726 }
717727}
718728
719- function dtoa_core ( buffer : usize , value : f64 ) : i32 {
729+ function dtoa_core ( buffer : usize , value : f64 , isSingle : bool ) : i32 {
720730 let sign = i32 ( value < 0 ) ;
721731 if ( sign ) {
722732 value = - value ;
723733 store < u16 > ( buffer , CharCode . MINUS ) ;
724734 }
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 ) ;
727737 len = prettify ( buffer + ( sign << 1 ) , len - sign , _K ) ;
728738 return len + sign ;
729739}
730740
731741// @ts -ignore: decorator
732742@lazy @inline const dtoa_buf = memory . data ( MAX_DOUBLE_LENGTH << 1 ) ;
733743
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 {
735752 if ( value == 0 ) return "0.0" ;
736753 if ( ! isFinite ( value ) ) {
737754 if ( isNaN ( value ) ) return "NaN" ;
738755 return select < String > ( "-Infinity" , "Infinity" , value < 0 ) ;
739756 }
740- let size = dtoa_core ( dtoa_buf , value ) << 1 ;
757+ let size = dtoa_core ( dtoa_buf , value , isSingle ) << 1 ;
741758 let result = changetype < String > ( __new ( size , idof < String > ( ) ) ) ;
742759 memory . copy ( changetype < usize > ( result ) , dtoa_buf , size ) ;
743760 return result ;
@@ -821,7 +838,14 @@ export function itoa_buffered<T extends number>(buffer: usize, value: T): u32 {
821838 return sign + decimals ;
822839}
823840
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 {
825849 if ( value == 0 ) {
826850 store < u16 > ( buffer , CharCode . _0 ) ;
827851 store < u16 > ( buffer , CharCode . DOT , 2 ) ;
@@ -845,5 +869,5 @@ export function dtoa_buffered(buffer: usize, value: f64): u32 {
845869 return 8 + u32 ( sign ) ;
846870 }
847871 }
848- return dtoa_core ( buffer , value ) ;
872+ return dtoa_core ( buffer , value , isSingle ) ;
849873}
0 commit comments