'How do I exactly convert a float to a fraction?
I was searching how to convert a float to the simplest fraction that would convert back to it and found this answer.
Problem is, the Python implementation given relies on the as_integer_ratio facility in the python standard library, which isn't present in Rust. I asked about this in a comment and found out about f64::frexp but I'm not sure I understand how it works, as its documentation is quite cryptic (to me at least):
Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
self = x * 2^exp0.5 <= abs(x) < 1.0
And on top of that, it's an unstable feature.
What should I do?
Solution 1:[1]
Algorithm apart, I guess the easiest way would be to use something working already, like the fraction crate:
From the example
use std::str::FromStr;
use fraction::{Fraction, Sign}; // choose the type accordingly with your needs (see prelude module docs)
fn main() {
// There are several ways to construct a fraction, depending on your use case
let f = Fraction::new(1u8, 2u8); // constructs with numerator/denominator and normalizes the fraction (finds least common denominator)
assert_eq!(f, Fraction::new_generic(Sign::Plus, 1i32, 2u8).unwrap()); // with numerator/denominator of different integer types
assert_eq!(f, Fraction::from(0.5)); // convert from float (f32, f64)
assert_eq!(f, Fraction::from_str("0.5").unwrap()); // parse a string
// Raw construct with no extra calculations.
// Most performant, but does not look for common denominator and may lead to unexpected results
// in following calculations. Only use if you are sure numerator/denominator are already normalized.
assert_eq!(f, Fraction::new_raw(1u64, 2u64));
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Netwave |
