aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-05-10 14:31:42 +0100
committerGitHub <noreply@github.com>2025-05-10 14:31:42 +0100
commitffb4b3655216c3624c08b2e1287f3eb5cfb9a8b9 (patch)
treee551665e234835e0b60ee39da81ee66b23f6aa8a
parente3fe733a555831342c54efdda36203132f2e8132 (diff)
parentebc63a73550b52f25c92f89f76760efc265e937f (diff)
Merge pull request #5143 from laytan/strconv-hexfloats
add hexfloat (0h) parsing to strconv
-rw-r--r--core/strconv/strconv.odin33
-rw-r--r--tests/core/strconv/test_core_strconv.odin37
2 files changed, 70 insertions, 0 deletions
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)