Merge pull request #5143 from laytan/strconv-hexfloats

add hexfloat (0h) parsing to strconv
This commit is contained in:
gingerBill
2025-05-10 14:31:42 +01:00
committed by GitHub
2 changed files with 70 additions and 0 deletions

View File

@@ -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

View File

@@ -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)