Hi,
In my crate GitHub - rsalmei/human-repr: Generate beautiful human representations of bytes, durations, and even throughputs!, I convert a number of seconds into a human friendly representation, so I'm used to f64s. But I'm having a hard time with a new, unreleased yet version.
I want this to be true (the p! macro is not important, I only format it with num.human_duration() to get the generated repr):
assert_eq!("19min 20.9s", p!(1160.9));
But unfortunately, only this works:
assert_eq!("19min 20.90000000000009s", p!(1160.9));
I know IEEE754 double-precision floating-point format does allow only 15-17 significant digits, what I'm I'm looking for here is some workaround...
Look, apparently they are precise:
println!("{}", 0.9f64);
println!("{}", 1160.9f64);
// 0.9
// 1160.9
But actually:
println!("{:58.53}", 0.9f64);
println!("{:58.53}", 1160.9f64);
// 0.90000000000000002220446049250313080847263336181640625
// 1160.90000000000009094947017729282379150390625000000000000
Well, what I want is exactly that previous behaviour, in that Rust somehow detects that the f64 has a lot of zeros, and decides to print a naked "{}" as 0.9
and 1160.9
. But, when calculating the minutes/seconds, the larger one shows it has lost precision on the seconds:
println!("{}", 0.9f64 % 60.0);
println!("{}", 1160.9f64 % 60.0);
// 0.9
// 20.90000000000009
If I were to "directly" print 20.9
, Rust does print it nicely:
println!("{}", 20.9f64);
// 20.9
I could manually print the original number into a String "1160.9", parse the decimal part as a new f64 "0.9", and use that, but I'd rather not do any heap allocations.
Any suggestions how I could polish the final number of seconds, please?