From ebc63a73550b52f25c92f89f76760efc265e937f Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 10 May 2025 15:11:52 +0200 Subject: [PATCH] add hexfloat (0h) parsing to strconv --- core/strconv/strconv.odin | 33 ++++++++++++++++++++ tests/core/strconv/test_core_strconv.odin | 37 +++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/core/strconv/strconv.odin b/core/strconv/strconv.odin index 26a737bd1..4cecd1911 100644 --- a/core/strconv/strconv.odin +++ b/core/strconv/strconv.odin @@ -1095,6 +1095,39 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) { return transmute(f64)bits, ok } + if len(str) > 2 && str[0] == '0' && str[1] == 'h' { + nr = 2 + + as_int: u64 + digits: int + for r in str[2:] { + if r == '_' { + nr += 1 + continue + } + v := u64(_digit_value(r)) + if v >= 16 { + break + } + as_int *= 16 + as_int += v + digits += 1 + } + nr += digits + ok = len(str) == nr + + switch digits { + case 4: + value = cast(f64)transmute(f16)cast(u16)as_int + case 8: + value = cast(f64)transmute(f32)cast(u32)as_int + case 16: + value = transmute(f64)as_int + case: + ok = false + } + return + } if value, nr, ok = check_special(str); ok { return diff --git a/tests/core/strconv/test_core_strconv.odin b/tests/core/strconv/test_core_strconv.odin index 6b70654cc..8266ece23 100644 --- a/tests/core/strconv/test_core_strconv.odin +++ b/tests/core/strconv/test_core_strconv.odin @@ -30,6 +30,43 @@ test_float :: proc(t: ^testing.T) { testing.expect_value(t, n, 0) testing.expect_value(t, ok, false) + f, ok = strconv.parse_f64("0", &n) + testing.expect_value(t, f, 0) + testing.expect_value(t, n, 1) + testing.expect_value(t, ok, true) + + f, ok = strconv.parse_f64("0h", &n) + testing.expect_value(t, f, 0) + testing.expect_value(t, n, 1) + testing.expect_value(t, ok, false) + + f, ok = strconv.parse_f64("0h1", &n) + testing.expect_value(t, f, 0) + testing.expect_value(t, n, 3) + testing.expect_value(t, ok, false) + + f, ok = strconv.parse_f64("0h0000_0001", &n) + testing.expect_value(t, f, 0h0000_0001) + testing.expect_value(t, n, 11) + testing.expect_value(t, ok, true) + + f, ok = strconv.parse_f64("0h4c60", &n) + testing.expect_value(t, f, 0h4c60) + testing.expect_value(t, f, 17.5) + testing.expect_value(t, n, 6) + testing.expect_value(t, ok, true) + + f, ok = strconv.parse_f64("0h418c0000", &n) + testing.expect_value(t, f, 0h418c0000) + testing.expect_value(t, f, 17.5) + testing.expect_value(t, n, 10) + testing.expect_value(t, ok, true) + + f, ok = strconv.parse_f64("0h4031_8000_0000_0000", &n) + testing.expect_value(t, f, 0h4031800000000000) + testing.expect_value(t, f, f64(17.5)) + testing.expect_value(t, n, 21) + testing.expect_value(t, ok, true) } @(test)