|
@@ -556,19 +556,49 @@ parse_f32 :: proc(s: string, n: ^int = nil) -> (value: f32, ok: bool) {
|
|
return f32(v), ok
|
|
return f32(v), ok
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
|
|
+ value, n^, ok = parse_f64_prefix(str)
|
|
|
|
+ if ok && len(str) != n^ {
|
|
|
|
+ ok = false
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+// Parses a 32-bit floating point number from a string.
|
|
|
|
+//
|
|
|
|
+// Returns ok=false if a base 10 float could not be found,
|
|
|
|
+// or if the input string contained more than just the number.
|
|
|
|
+//
|
|
|
|
+// ```
|
|
|
|
+// n, _, ok := strconv.parse_f32("12.34eee");
|
|
|
|
+// assert(n == 12.34 && ok);
|
|
|
|
+//
|
|
|
|
+// n, _, ok = strconv.parse_f32("12.34");
|
|
|
|
+// assert(n == 12.34 && ok);
|
|
|
|
+// ```
|
|
|
|
+parse_f32_prefix :: proc(str: string) -> (value: f32, nr: int, ok: bool) {
|
|
|
|
+ f: f64
|
|
|
|
+ f, nr, ok = parse_f64_prefix(str)
|
|
|
|
+ value = f32(f)
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
// Parses a 64-bit floating point number from a string.
|
|
// Parses a 64-bit floating point number from a string.
|
|
//
|
|
//
|
|
// Returns ok=false if a base 10 float could not be found,
|
|
// Returns ok=false if a base 10 float could not be found,
|
|
// or if the input string contained more than just the number.
|
|
// or if the input string contained more than just the number.
|
|
//
|
|
//
|
|
// ```
|
|
// ```
|
|
-// n, ok := strconv.parse_f32("12.34eee");
|
|
|
|
|
|
+// n, _, ok := strconv.parse_f32("12.34eee");
|
|
// assert(n == 12.34 && ok);
|
|
// assert(n == 12.34 && ok);
|
|
//
|
|
//
|
|
-// n, ok = strconv.parse_f32("12.34");
|
|
|
|
|
|
+// n, _, ok = strconv.parse_f32("12.34");
|
|
// assert(n == 12.34 && ok);
|
|
// assert(n == 12.34 && ok);
|
|
// ```
|
|
// ```
|
|
-parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
|
|
|
|
+parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
|
|
common_prefix_len_ignore_case :: proc "contextless" (s, prefix: string) -> int {
|
|
common_prefix_len_ignore_case :: proc "contextless" (s, prefix: string) -> int {
|
|
n := len(prefix)
|
|
n := len(prefix)
|
|
if n > len(s) {
|
|
if n > len(s) {
|
|
@@ -751,7 +781,7 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
mantissa |= 1
|
|
mantissa |= 1
|
|
}
|
|
}
|
|
|
|
|
|
- for mantissa >> (info.mantbits+2) == 0 {
|
|
|
|
|
|
+ for mantissa != 0 && mantissa >> (info.mantbits+2) == 0 {
|
|
mantissa = mantissa>>1 | mantissa&1
|
|
mantissa = mantissa>>1 | mantissa&1
|
|
exp += 1
|
|
exp += 1
|
|
}
|
|
}
|
|
@@ -795,9 +825,6 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- nr: int
|
|
|
|
- defer if n != nil { n^ = nr }
|
|
|
|
-
|
|
|
|
if value, nr, ok = check_special(str); ok {
|
|
if value, nr, ok = check_special(str); ok {
|
|
return
|
|
return
|
|
}
|
|
}
|
|
@@ -808,7 +835,8 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
mantissa, exp, neg, trunc, hex, nr = parse_components(str) or_return
|
|
mantissa, exp, neg, trunc, hex, nr = parse_components(str) or_return
|
|
|
|
|
|
if hex {
|
|
if hex {
|
|
- return parse_hex(str, mantissa, exp, neg, trunc)
|
|
|
|
|
|
+ value, ok = parse_hex(str, mantissa, exp, neg, trunc)
|
|
|
|
+ return
|
|
}
|
|
}
|
|
|
|
|
|
trunc_block: if !trunc {
|
|
trunc_block: if !trunc {
|
|
@@ -827,7 +855,7 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
}
|
|
}
|
|
switch {
|
|
switch {
|
|
case exp == 0:
|
|
case exp == 0:
|
|
- return f, true
|
|
|
|
|
|
+ return f, nr, true
|
|
case exp > 0 && exp <= 15+22:
|
|
case exp > 0 && exp <= 15+22:
|
|
if exp > 22 {
|
|
if exp > 22 {
|
|
f *= pow10[exp-22]
|
|
f *= pow10[exp-22]
|
|
@@ -836,9 +864,9 @@ parse_f64 :: proc(str: string, n: ^int = nil) -> (value: f64, ok: bool) {
|
|
if f > 1e15 || f < 1e-15 {
|
|
if f > 1e15 || f < 1e-15 {
|
|
break trunc_block
|
|
break trunc_block
|
|
}
|
|
}
|
|
- return f * pow10[exp], true
|
|
|
|
|
|
+ return f * pow10[exp], nr, true
|
|
case -22 <= exp && exp < 0:
|
|
case -22 <= exp && exp < 0:
|
|
- return f / pow10[-exp], true
|
|
|
|
|
|
+ return f / pow10[-exp], nr, true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
d: decimal.Decimal
|
|
d: decimal.Decimal
|