The values of A and B will be rounded off to the nearest representable f64 value, which happen to be the same. A - B will evaluate to 0 and your assertion will succeed (when it shouldn't).
If this kind of exact arithmetic is important to you, perhaps a crate like rust_decimal would be a better fit.
For example:
use rust_decimal::Decimal;
use rust_decimal_macros::dec;
fn main() {
let A: Decimal = dec!(98148824396622615.0);
let B: Decimal = dec!(98148824396622610.0);
println!("{A}");
assert_eq!(A - B, dec!(5)); // OK
println!("{}", A - B);
}
Concretely, the largest integer value you can store in f64, without an omitted integer value below it, is 253 = 9,007,199,254,740,991.0. That's a tenth of your numbers.
Given that floats are fuzzy, is this in fact a bug?
...and while I don't see an explicit answer, it seems the answer is "no". I especially appreciate the pointer to rust_decimal, and suspect its implementation is similar to that of the other language I was looking at.
I agree that the answer is "no". All the standard numeric types in Rust are clearly marked as limited-precision (e.g. the 64 in f64), and the two numbers A and B are not exactly representable as f64 values, so erroneous results from calculations are only to be expected. Other replies have given useful details about how this loss of precision works.
The numeric types in rust_decimal and similar crates are also of limited precision, but you can probably use them for a lot longer before running into errors, at the cost of (slightly) more memory usage and computation time.
I managed to make rust_decimal work. The problem turned out to be the well-known issue of instability when pivoting a matrix. Delicate handling very small absolute values solved the problem.
Were I to think more carefully about what I am doing, I might could remove the guard, but I am not sure about that.