If you have to rely on predictable mathematical accuracy (for example you are doing financial calculations), never use floating point arithmetic (so types prefixed with f in Rust). The way to go is fixed point aritthmetic. There is no native type for fixed point decimal arithmetic, but decimal crate does its job.
To broaden the topic, rationals give you pretty good accuracy as well as predictability and you can do other cool stuff with them. I might write a crate for that sometime.
In this case, (42 + 31)/10 = (41 + 32) / 10, with no room for errors.
You have just discovered that you don't understand floating point numbers. Most computers/languages today use the IEEE 754 standard for floating point number representation IEEE 754 - Wikipedia Given that we are representing decimal numbers in binary there are rounding "errors" all over the place. It's just not possible to have exact representations for most real numbers.
If you sit down with pencil an paper out work through those sums using the binary representation you will see why it seems to go wrong.
In general one should never compare floating point numbers for equality. Things that look like they should be equal usually are not, like your example:
For an in-depth treatment of how weird IEEE-754 floating point gets and how to handle it properly, I recommend reading through David Goldberg's classic "What Every Computer Scientist Should Know About Floating-Point Arithmetic" guide. Various copies are available online.
If you realy want to compare two floats you can check if their difference is less than the machine's minimal float-step. This value is usually somewhere available as a constant called EPSILON. In Rust is is either std::f32::EPSILON or std::f64::EPSILON. For example: