diff --git a/core/strconv/fast_float.odin b/core/strconv/fast_float.odin index 0fcf597d6..d1a45d952 100644 --- a/core/strconv/fast_float.odin +++ b/core/strconv/fast_float.odin @@ -28,7 +28,7 @@ _ :: bits // needed for STRCONV_FAST_FLOAT=false /* Disable with `-define:STRCONV_FAST_FLOAT=false` to drop the Eisel-Lemire step - and its table. + and its table, and to read digits one at a time (instead of eight). */ FAST_FLOAT :: #config(STRCONV_FAST_FLOAT, true) @@ -183,7 +183,9 @@ parse_number_string :: #force_inline proc "contextless" (s: string) -> (mantissa if i < n && s[i] == '.' { i += 1 frac_start := i - i, mantissa = loop_parse_if_eight_digits(s, i, mantissa) + when FAST_FLOAT { + i, mantissa = loop_parse_if_eight_digits(s, i, mantissa) + } for i < n && s[i] - '0' <= 9 { mantissa = mantissa*10 + u64(s[i] - '0') i += 1 diff --git a/core/strconv/hex_float.odin b/core/strconv/hex_float.odin index a6dffd9a3..5dab19fcd 100644 --- a/core/strconv/hex_float.odin +++ b/core/strconv/hex_float.odin @@ -36,15 +36,17 @@ scan_hex_float :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, ne saw_digits ||= s[i] == '0' i += 1 } - for i+8 <= n && nd+8 <= MAX_HEX_DIGITS { - v := read8_to_u64(s, i) - if !is_eight_hex_digits(v) { - break + when FAST_FLOAT { + for i+8 <= n && nd+8 <= MAX_HEX_DIGITS { + v := read8_to_u64(s, i) + if !is_eight_hex_digits(v) { + break + } + mantissa = mantissa<<32 | parse_eight_hex_digits(v) + nd += 8 + i += 8 + saw_digits = true } - mantissa = mantissa<<32 | parse_eight_hex_digits(v) - nd += 8 - i += 8 - saw_digits = true } for i < n { d := hex_digit_table[s[i]] @@ -76,27 +78,29 @@ scan_hex_float :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, ne i += 1 } } - for i+8 <= n && nd+8 <= MAX_HEX_DIGITS { - v := read8_to_u64(s, i) - if !is_eight_hex_digits(v) { - break - } - mantissa = mantissa<<32 | parse_eight_hex_digits(v) - nd += 8 - exp -= 32 - i += 8 - saw_digits = true - } - if i+4 <= n && nd+4 <= MAX_HEX_DIGITS { - // Four digits: pad them with "0000" and use the 8-digit code. - v := u64(read4_to_u32(s, i)) | 0x3030_3030 << 32 - if is_eight_hex_digits(v) { - mantissa = mantissa<<16 | parse_eight_hex_digits(v) >> 16 - nd += 4 - exp -= 16 - i += 4 + when FAST_FLOAT { + for i+8 <= n && nd+8 <= MAX_HEX_DIGITS { + v := read8_to_u64(s, i) + if !is_eight_hex_digits(v) { + break + } + mantissa = mantissa<<32 | parse_eight_hex_digits(v) + nd += 8 + exp -= 32 + i += 8 saw_digits = true } + if i+4 <= n && nd+4 <= MAX_HEX_DIGITS { + // Four digits: pad them with "0000" and use the 8-digit code. + v := u64(read4_to_u32(s, i)) | 0x3030_3030 << 32 + if is_eight_hex_digits(v) { + mantissa = mantissa<<16 | parse_eight_hex_digits(v) >> 16 + nd += 4 + exp -= 16 + i += 4 + saw_digits = true + } + } } for i < n { d := hex_digit_table[s[i]] diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 7b7a9ce50..dbae1efe6 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -974,24 +974,28 @@ parse_float_prefix_generic :: proc($T: typeid, str: string) -> (value: T, nr: in i := 2 // Read 8 hex digits at a time, then 4 digits at a time (like "0h3c00" or groups // between `_` separators), then single digits and `_` separators. - for i+8 <= len(str) { - v := read8_to_u64(str, i) - if !is_eight_hex_digits(v) { - break + when FAST_FLOAT { + for i+8 <= len(str) { + v := read8_to_u64(str, i) + if !is_eight_hex_digits(v) { + break + } + as_int = as_int<<32 | parse_eight_hex_digits(v) + digits += 8 + i += 8 } - as_int = as_int<<32 | parse_eight_hex_digits(v) - digits += 8 - i += 8 } for i < len(str) { - if i+4 <= len(str) { - // Four digits: pad them with "0000" and use the 8-digit code. - v := u64(read4_to_u32(str, i)) | 0x3030_3030 << 32 - if is_eight_hex_digits(v) { - as_int = as_int<<16 | parse_eight_hex_digits(v) >> 16 - digits += 4 - i += 4 - continue + when FAST_FLOAT { + if i+4 <= len(str) { + // Four digits: pad them with "0000" and use the 8-digit code. + v := u64(read4_to_u32(str, i)) | 0x3030_3030 << 32 + if is_eight_hex_digits(v) { + as_int = as_int<<16 | parse_eight_hex_digits(v) >> 16 + digits += 4 + i += 4 + continue + } } } if str[i] != '_' {