mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 22:58:46 +00:00
Permit parsing of incomplete infinity but do not return true
To clarify, `parse_f64` will indeed take `infi` to mean `+Inf` and return that as the value, but it will not return `ok = true`. It treats it as `inf` followed by any other trailing character. `parse_f64_prefix` is the lenient one which will return true so long as it finds some meaningful value.
This commit is contained in:
@@ -879,9 +879,15 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
case 'i', 'I':
|
case 'i', 'I':
|
||||||
m := common_prefix_len_ignore_case(s, "infinity")
|
m := common_prefix_len_ignore_case(s, "infinity")
|
||||||
if m == 3 || m == 8 { // "inf" or "infinity"
|
if 3 <= m && m < 9 { // "inf" to "infinity"
|
||||||
f = 0h7ff00000_00000000 if sign == 1 else 0hfff00000_00000000
|
f = 0h7ff00000_00000000 if sign == 1 else 0hfff00000_00000000
|
||||||
n = nsign + m
|
if m == 8 {
|
||||||
|
// We only count the entire prefix if it is precisely "infinity".
|
||||||
|
n = nsign + m
|
||||||
|
} else {
|
||||||
|
// The string was either only "inf" or incomplete.
|
||||||
|
n = nsign + 3
|
||||||
|
}
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,18 +62,15 @@ test_infinity :: proc(t: ^testing.T) {
|
|||||||
n: int
|
n: int
|
||||||
s := "infinity"
|
s := "infinity"
|
||||||
|
|
||||||
for i in 1 ..< len(s) + 1 {
|
for i in 0 ..< len(s) + 1 {
|
||||||
ss := s[:i]
|
ss := s[:i]
|
||||||
f, ok := strconv.parse_f64(ss, &n)
|
f, ok := strconv.parse_f64(ss, &n)
|
||||||
if i == 3 { // "inf"
|
if i >= 3 { // "inf" .. "infinity"
|
||||||
|
expected_n := 8 if i == 8 else 3
|
||||||
|
expected_ok := i == 3 || i == 8
|
||||||
testing.expect_value(t, f, pos_inf)
|
testing.expect_value(t, f, pos_inf)
|
||||||
testing.expect_value(t, n, 3)
|
testing.expect_value(t, n, expected_n)
|
||||||
testing.expect_value(t, ok, true)
|
testing.expect_value(t, ok, expected_ok)
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
|
||||||
} else if i == 8 { // "infinity"
|
|
||||||
testing.expect_value(t, f, pos_inf)
|
|
||||||
testing.expect_value(t, n, 8)
|
|
||||||
testing.expect_value(t, ok, true)
|
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||||
} else { // invalid substring
|
} else { // invalid substring
|
||||||
testing.expect_value(t, f, 0)
|
testing.expect_value(t, f, 0)
|
||||||
@@ -84,18 +81,15 @@ test_infinity :: proc(t: ^testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = "+infinity"
|
s = "+infinity"
|
||||||
for i in 1 ..< len(s) + 1 {
|
for i in 0 ..< len(s) + 1 {
|
||||||
ss := s[:i]
|
ss := s[:i]
|
||||||
f, ok := strconv.parse_f64(ss, &n)
|
f, ok := strconv.parse_f64(ss, &n)
|
||||||
if i == 4 { // "+inf"
|
if i >= 4 { // "+inf" .. "+infinity"
|
||||||
|
expected_n := 9 if i == 9 else 4
|
||||||
|
expected_ok := i == 4 || i == 9
|
||||||
testing.expect_value(t, f, pos_inf)
|
testing.expect_value(t, f, pos_inf)
|
||||||
testing.expect_value(t, n, 4)
|
testing.expect_value(t, n, expected_n)
|
||||||
testing.expect_value(t, ok, true)
|
testing.expect_value(t, ok, expected_ok)
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
|
||||||
} else if i == 9 { // "+infinity"
|
|
||||||
testing.expect_value(t, f, pos_inf)
|
|
||||||
testing.expect_value(t, n, 9)
|
|
||||||
testing.expect_value(t, ok, true)
|
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
testing.expect_value(t, math.classify(f), math.Float_Class.Inf)
|
||||||
} else { // invalid substring
|
} else { // invalid substring
|
||||||
testing.expect_value(t, f, 0)
|
testing.expect_value(t, f, 0)
|
||||||
@@ -106,18 +100,15 @@ test_infinity :: proc(t: ^testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s = "-infinity"
|
s = "-infinity"
|
||||||
for i in 1 ..< len(s) + 1 {
|
for i in 0 ..< len(s) + 1 {
|
||||||
ss := s[:i]
|
ss := s[:i]
|
||||||
f, ok := strconv.parse_f64(ss, &n)
|
f, ok := strconv.parse_f64(ss, &n)
|
||||||
if i == 4 { // "-inf"
|
if i >= 4 { // "-inf" .. "infinity"
|
||||||
|
expected_n := 9 if i == 9 else 4
|
||||||
|
expected_ok := i == 4 || i == 9
|
||||||
testing.expect_value(t, f, neg_inf)
|
testing.expect_value(t, f, neg_inf)
|
||||||
testing.expect_value(t, n, 4)
|
testing.expect_value(t, n, expected_n)
|
||||||
testing.expect_value(t, ok, true)
|
testing.expect_value(t, ok, expected_ok)
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Neg_Inf)
|
|
||||||
} else if i == 9 { // "-infinity"
|
|
||||||
testing.expect_value(t, f, neg_inf)
|
|
||||||
testing.expect_value(t, n, 9)
|
|
||||||
testing.expect_value(t, ok, true)
|
|
||||||
testing.expect_value(t, math.classify(f), math.Float_Class.Neg_Inf)
|
testing.expect_value(t, math.classify(f), math.Float_Class.Neg_Inf)
|
||||||
} else { // invalid substring
|
} else { // invalid substring
|
||||||
testing.expect_value(t, f, 0)
|
testing.expect_value(t, f, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user