@@ -418,6 +418,52 @@ export function dtoa<T extends number>(value: T): String {
418418 if ( isNaN ( value ) ) return "NaN" ;
419419 return select < String > ( "-Infinity" , "Infinity" , value < 0 ) ;
420420 }
421+ // Exact integers in this range can be written into their final allocation.
422+ // The f32 limit matters: larger integral f32 values can have a shorter
423+ // decimal representation than their exact integer value.
424+ let exactIntegerRange = false ;
425+ if ( isFloat < T > ( ) ) {
426+ if ( sizeof < T > ( ) == 4 ) {
427+ let bits = reinterpret < u32 > ( < f32 > value ) & 0x7fffffff ;
428+ exactIntegerRange = bits >= 0x3f800000 && bits <= 0x4b800000 ;
429+ } else {
430+ let bits = reinterpret < u64 > ( < f64 > value ) & 0x7fffffffffffffff ;
431+ exactIntegerRange = bits >= 0x3ff0000000000000 && bits <= 0x41cdcd6500000000 ;
432+ }
433+ }
434+ if ( exactIntegerRange ) {
435+ let integer = < i32 > value ;
436+ if ( value == < T > integer ) {
437+ let negative = integer < 0 ;
438+ let magnitude = < u32 > ( negative ? - integer : integer ) ;
439+ let digits = decimalCount32 ( magnitude ) ;
440+ let result = changetype < String > ( __new ( < usize > ( digits + u32 ( negative ) + 2 ) << 1 , idof < String > ( ) ) ) ;
441+ let out = changetype < usize > ( result ) ;
442+ if ( negative ) {
443+ store < u16 > ( out , CharCode . MINUS ) ;
444+ out += 2 ;
445+ }
446+ if ( magnitude < 10 ) {
447+ store < u16 > ( out , CharCode . _0 + magnitude ) ;
448+ } else if ( magnitude < 100 ) {
449+ store < u32 > ( out , load < u32 > ( DIGITS + ( < usize > magnitude << 2 ) ) ) ;
450+ } else if ( magnitude < 10000 ) {
451+ let high = magnitude / 100 ;
452+ let low = magnitude - high * 100 ;
453+ if ( magnitude < 1000 ) {
454+ store < u16 > ( out , CharCode . _0 + high ) ;
455+ store < u32 > ( out + 2 , load < u32 > ( DIGITS + ( < usize > low << 2 ) ) ) ;
456+ } else {
457+ store < u32 > ( out , load < u32 > ( DIGITS + ( < usize > high << 2 ) ) ) ;
458+ store < u32 > ( out + 4 , load < u32 > ( DIGITS + ( < usize > low << 2 ) ) ) ;
459+ }
460+ } else {
461+ utoa32_dec_core ( out , magnitude , digits ) ;
462+ }
463+ store < u32 > ( out + ( < usize > digits << 1 ) , < u32 > CharCode . DOT | ( < u32 > CharCode . _0 << 16 ) ) ;
464+ return result ;
465+ }
466+ }
421467 let len : u32 ;
422468 if ( isFloat < T > ( ) && sizeof < T > ( ) == 4 ) {
423469 // @ts -ignore: type
0 commit comments