When subtracting two nearby f64 floats, I am observing a result with higher precision than the f64 format's standard precision. Typically, I would expect around 15-16 decimal places,…
f64
does not have a “standard precision” of 15-16 decimal places. Its precision is 53 binary digits.
When the source text 0.01053710310220
is compiled, it is converted to the nearest value representable in f64
, which is 0.01053710310219999925218647973679253482259809970855712890625, which is 6,074,226,381,392,949•2−59. (Observe that 6,074,226,381,392,949 fits in 53 bits, the precision of f64
.) When -0.01053710310221
is compiled, it is converted to −0.0105371031022099999330254860296918195672333240509033203125, which is −6,074,226,381,398,714•2−59. When these are added, the result is −5,765•2−59, which is exactly −0.00000000000001000068083900629289928474463522434234619140625.
You can subtract 6,074,226,381,398,714 from 6,074,226,381,392,949 by eye—most of the leading digits cancel, and it is just 8,714−2,949—and verify the result, 5,765, is correct. And so you can see no extra precision appeared.
… enforces variables to adhere to the standard number of decimals dictated by their format?
There is nothing in the standard for this format, IEEE 754, that dictates a number of decimals.
How can I address precision issues with f64 variables in Rust?
This is too vague and broad a question. Do you want to work with 16-digit decimal numbers? At a fixed scale or at a varying scale? What operations do you need to do with them—just addition, as you have shown, or other elementary arithmetic? Do you need square roots, sines, logarithms, and other functions? What is the range of numbers you need to work with? Do you need exact results or can you accept approximations? How much?