This is a really big distinction but is only mentioned in passing in BOL (check here), but approximate numerics are just that: approximate. Someone who understands the storage engine better can explain why a foat or real can’t store an exact number, but they can’t and don’t. You might put 1.5 into it and later come to find that the value is 1.4999.
If you need an exact representation of a number that isn’t an integer, you need to use numeric or decimal. These are functionally the same, so it doesn’t matter which you choose.