"83.79".to_d is representing the fraction 8379/100 exactly in internal representation because it uses a base 10 (or a power of it), while "83.79".to_f is not because internal representation uses a base 2, so these are not equal.
That's not the same for 83.75 because is is represented exactly in both base 2 and 10 (this is 83 + 1/2 + 1/4).
If you mix big decimals and floats in the same expression, floats are then converted to the nearest big decimal... Thus, you are in fact performing this: 83.79.to_d
or put differently "83.79".to_f.to_d
Since "83.79".to_f
is not exact, and since big decimal is more accurate than float, there's no reason that it matches "83.79".to_d
.
However, if you force the conversion the other way, I would expect that equality holds:
expect("83.79".to_d.to_f).to eq(83.79)
This is because we can reasonnably expect (least astonishment) that conversions to_f will answer the nearest floating point to the exact fraction, be it from an exact big decimal or a string representation.