@@ -4,10 +4,10 @@ import { idof } from "../builtins";
44import { CharCode } from "./string" ;
55import * as floatFormat from "./dtoa" ;
66
7- // >= 32 code units (64 bytes) per value
7+ // 28 code units (56 bytes) per value, including full digit-block stores.
88// @ts -ignore: decorator
99@inline
10- export const MAX_DOUBLE_LENGTH = 32 ;
10+ export const MAX_DOUBLE_LENGTH = 28 ;
1111
1212/*
1313 Lookup table for pairwise char codes in range [0-99]
@@ -418,50 +418,53 @@ 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 ;
421+ // Avoid the specialized integer writer when optimizing for code size.
422+ if ( ASC_SHRINK_LEVEL == 0 ) {
423+ // Exact integers in this range can be written into their final allocation.
424+ // The f32 limit matters: larger integral f32 values can have a shorter
425+ // decimal representation than their exact integer value.
426+ let exactIntegerRange = false ;
427+ if ( isFloat < T > ( ) ) {
428+ if ( sizeof < T > ( ) == 4 ) {
429+ let bits = reinterpret < u32 > ( < f32 > value ) & 0x7fffffff ;
430+ exactIntegerRange = bits >= 0x3f800000 && bits <= 0x4b800000 ;
431+ } else {
432+ let bits = reinterpret < u64 > ( < f64 > value ) & 0x7fffffffffffffff ;
433+ exactIntegerRange = bits >= 0x3ff0000000000000 && bits <= 0x41cdcd6500000000 ;
445434 }
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 ) ) ) ;
435+ }
436+ if ( exactIntegerRange ) {
437+ let integer = < i32 > value ;
438+ if ( value == < T > integer ) {
439+ let negative = integer < 0 ;
440+ let magnitude = < u32 > ( negative ? - integer : integer ) ;
441+ let digits = decimalCount32 ( magnitude ) ;
442+ let result = changetype < String > ( __new ( < usize > ( digits + u32 ( negative ) + 2 ) << 1 , idof < String > ( ) ) ) ;
443+ let out = changetype < usize > ( result ) ;
444+ if ( negative ) {
445+ store < u16 > ( out , CharCode . MINUS ) ;
446+ out += 2 ;
447+ }
448+ if ( magnitude < 10 ) {
449+ store < u16 > ( out , CharCode . _0 + magnitude ) ;
450+ } else if ( magnitude < 100 ) {
451+ store < u32 > ( out , load < u32 > ( DIGITS + ( < usize > magnitude << 2 ) ) ) ;
452+ } else if ( magnitude < 10000 ) {
453+ let high = magnitude / 100 ;
454+ let low = magnitude - high * 100 ;
455+ if ( magnitude < 1000 ) {
456+ store < u16 > ( out , CharCode . _0 + high ) ;
457+ store < u32 > ( out + 2 , load < u32 > ( DIGITS + ( < usize > low << 2 ) ) ) ;
458+ } else {
459+ store < u32 > ( out , load < u32 > ( DIGITS + ( < usize > high << 2 ) ) ) ;
460+ store < u32 > ( out + 4 , load < u32 > ( DIGITS + ( < usize > low << 2 ) ) ) ;
461+ }
456462 } else {
457- store < u32 > ( out , load < u32 > ( DIGITS + ( < usize > high << 2 ) ) ) ;
458- store < u32 > ( out + 4 , load < u32 > ( DIGITS + ( < usize > low << 2 ) ) ) ;
463+ utoa32_dec_core ( out , magnitude , digits ) ;
459464 }
460- } else {
461- utoa32_dec_core ( out , magnitude , digits ) ;
465+ store < u32 > ( out + ( < usize > digits << 1 ) , < u32 > CharCode . DOT | ( < u32 > CharCode . _0 << 16 ) ) ;
466+ return result ;
462467 }
463- store < u32 > ( out + ( < usize > digits << 1 ) , < u32 > CharCode . DOT | ( < u32 > CharCode . _0 << 16 ) ) ;
464- return result ;
465468 }
466469 }
467470 let len : u32 ;
0 commit comments