From d3e820c1202434162e6967e524ec822689ced82e Mon Sep 17 00:00:00 2001 From: fmoletta <99273364+fmoletta@users.noreply.github.com> Date: Tue, 6 Jun 2023 00:54:29 +0300 Subject: [PATCH] Fix deserialization of scientific notation with fractional values (#1202) * First draft * Simplify implementation * Remove test * Add changelog entry * Clippy --- CHANGELOG.md | 2 ++ src/serde/deserialize_program.rs | 44 +++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30eab4396c..fe809d3269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* bugfix: Fix deserialization of scientific notation with fractional values [#1202](https://github.com/lambdaclass/cairo-rs/pull/1202) + * feat: implement `mem_eq` function to test for equality of two ranges in memory [#1198](https://github.com/lambdaclass/cairo-rs/pull/1198) * perf: use `mem_eq` in `set_add` [#1198](https://github.com/lambdaclass/cairo-rs/pull/1198) diff --git a/src/serde/deserialize_program.rs b/src/serde/deserialize_program.rs index d4296fa51d..1b92a5c4c5 100644 --- a/src/serde/deserialize_program.rs +++ b/src/serde/deserialize_program.rs @@ -187,14 +187,17 @@ where } fn deserialize_scientific_notation(n: Number) -> Option { - let str = n.to_string(); - let list: [&str; 2] = str.split('e').collect::>().try_into().ok()?; - - let base = Felt252::parse_bytes(list[0].to_string().as_bytes(), 10)?; - let exponent = list[1].parse::().ok()?; + match n.as_f64() { + None => { + let str = n.to_string(); + let list: [&str; 2] = str.split('e').collect::>().try_into().ok()?; - let result = base * Felt252::from(10).pow(exponent); - Some(result) + let exponent = list[1].parse::().ok()?; + let base = Felt252::parse_bytes(list[0].to_string().as_bytes(), 10)?; + Some(base * Felt252::from(10).pow(exponent)) + } + Some(float) => Felt252::parse_bytes(float.round().to_string().as_bytes(), 10), + } } #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] @@ -1437,4 +1440,31 @@ mod tests { Ok(x) if x == Some(Felt252::one() * Felt252::from(10).pow(27)) ); } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_felt_from_number_with_scientific_notation_with_fractional_part() { + let n = serde_json::Value::Number(Number::from_f64(64e+74).unwrap()); + + assert_matches!( + felt_from_number(n), + Ok(x) if x == Some(Felt252::from_str_radix("64", 10).unwrap() * Felt252::from(10).pow(74)) + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_felt_from_number_with_scientific_notation_with_fractional_part_f64_max() { + let n = serde_json::Value::Number(Number::from_f64(f64::MAX).unwrap()); + assert_eq!( + felt_from_number(n).unwrap(), + Some( + Felt252::from_str_radix( + "2082797363194934431336897723140298717588791783575467744530053896730196177808", + 10 + ) + .unwrap() + ) + ); + } }