///|
/// Parse a numeric string with the shared Python float-text semantics.
pub fn parse_float_text(value : String) -> Double raise @core.DataError {
log_text_float(value)
}
///|
// Python float(str) shares decimal digits and outer whitespace with the
// existing int-text consumer, but has no integer digit limit or repr truncation.
fn log_text_float(value : String) -> Double raise @core.DataError {
let characters = value.to_array()
let mut first = 0
let mut last = characters.length()
while first < last && percent_precision_space(characters[first]) {
first += 1
}
while last > first && percent_precision_space(characters[last - 1]) {
last -= 1
}
let negative = first < last && characters[first] == '-'
let normalized = StringBuilder()
for index in first.. normalized.write_string(digit.to_string())
None => normalized.write_char(characters[index])
}
}
let text = normalized.to_string()
let number = @string.parse_double(text[:]) catch {
Failure::Failure("value out of range") =>
if negative {
-1.0 / 0.0
} else {
1.0 / 0.0
}
_ =>
raise @core.DataError::InvalidTicks(
message="ValueError: could not convert string to float: " +
method_quote(value),
)
}
// The core parser intentionally canonicalizes NaN without its textual sign.
// The original float constructor preserves that sign, as well as signed zero.
if number.is_nan() {
if negative {
0xfff8000000000000UL.reinterpret_as_double()
} else {
0x7ff8000000000000UL.reinterpret_as_double()
}
} else if number == 0.0 && negative {
-0.0
} else {
number
}
}