This is essentially correct, with just a thing worth clarifying.
What happens is that the value is approximated at the moment it’s created, because it has to be represented in binary using floating-point. Internally, the system then works with that binary approximation.
When the value is later converted to a string for display, there’s another rounding step involved, but this doesn’t introduce a new error — it simply makes the existing approximation visible.
(An alternative, mentioned in this thread, is a better convertion method into/from string, but that’s another thread)
So you can think of it as two stages:
- the approximation needed to store the number in binary
- the purely presentational rounding as decimal text