forked from Rust-related/RustPython
Improve float.fromhex module of objfloat (#1552)
* Improve float.fromhex module of objfloat - Python float.fromhex can handle string of float and hex without `.` - For example '0.0', '-0.0', '0x0p0', '-0x0p0' - Add test case mantioned * Change unwrap to expect for error handling * Improve error handling with pattern matching - `expect` that can't express python vm error message changed to pattern match - Erase duplicated test case * Refactoring with or_else and map_err - Use `or_else` instead of value condition and `match` statement - For floating-point input - Use `map_err` instead of `match ` statement - For hexadecimal floating-point input without dot * Add else condition
This commit is contained in:
@@ -240,12 +240,21 @@ a = 3.1__4
|
||||
with assert_raises(SyntaxError):
|
||||
exec(src)
|
||||
|
||||
assert float.fromhex('0.0') == 0.0
|
||||
assert float.fromhex('-0.0') == 0.0
|
||||
assert float.fromhex('0x0p0') == 0.0
|
||||
assert float.fromhex('0x010p0') == 16.0
|
||||
assert float.fromhex('0x0.10p3') == 0.5
|
||||
assert float.fromhex('-0x0p0') == 0.0
|
||||
assert float.fromhex('0x0.p0') == 0.0
|
||||
assert float.fromhex('-0x0.p0') == 0.0
|
||||
assert float.fromhex('0x0.0p+0') == 0.0
|
||||
assert float.fromhex('-0x0.0p+0') == -0.0
|
||||
assert float.fromhex('0x1.000000p+0') == 1.0
|
||||
assert float.fromhex('-0x1.800000p+0') == -1.5
|
||||
assert float.fromhex('inf') == float('inf')
|
||||
assert math.isnan(float.fromhex('nan'))
|
||||
assert_raises(ValueError, lambda: float.fromhex('error'))
|
||||
|
||||
assert (0.0).hex() == '0x0.0p+0'
|
||||
assert (-0.0).hex() == '-0x0.0p+0'
|
||||
|
||||
@@ -583,12 +583,30 @@ impl PyFloat {
|
||||
|
||||
#[pymethod]
|
||||
fn fromhex(repr: PyStringRef, vm: &VirtualMachine) -> PyResult<f64> {
|
||||
hexf_parse::parse_hexf64(repr.as_str(), false).or_else(|_| match repr.as_str() {
|
||||
"nan" => Ok(std::f64::NAN),
|
||||
"inf" => Ok(std::f64::INFINITY),
|
||||
"-inf" => Ok(std::f64::NEG_INFINITY),
|
||||
_ => Err(vm.new_value_error("invalid hexadecimal floating-point string".to_string())),
|
||||
})
|
||||
hexf_parse::parse_hexf64(repr.as_str(), false)
|
||||
.or_else(|_| repr.as_str().parse::<f64>())
|
||||
.or_else(|_| match repr.as_str() {
|
||||
"nan" => Ok(std::f64::NAN),
|
||||
"inf" => Ok(std::f64::INFINITY),
|
||||
"-inf" => Ok(std::f64::NEG_INFINITY),
|
||||
value => {
|
||||
let mut hex = String::new();
|
||||
if value.contains("0x") {
|
||||
for ch in value.chars() {
|
||||
if ch == 'p' {
|
||||
hex.push_str(".p");
|
||||
} else {
|
||||
hex.push(ch);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
hex = value.to_string();
|
||||
}
|
||||
hexf_parse::parse_hexf64(hex.as_str(), false).map_err(|_| {
|
||||
vm.new_value_error("invalid hexadecimal floating-point string".to_string())
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
|
||||
Reference in New Issue
Block a user