Instead it's more accurate to think of them as being in scientific notation like 1.23E-1.
In this notation it's clearer that they're sparsely populated because some of the 32 bits encode the exponent, which grows and shrinks very quickly.
But yes rationals are reals. It's clear that you can't represent, say, all digits of pi in 32 bits, so the parent comment was not saying that 32 bit floats are all of the reals.
It's generally accurate to consider floats an acceptable approximation of the [extended] reals, since it's possible to do operations on them that don't exist for rational numbers, like sqrt or exp.
This kinda sent me on a spin, for a moment I thought my whole life was a lie and these functions don't take rationals as inputs somehow. Then I realized you mean rather that they typically produce non-rationals, so the outputs will be approximated.
That said, I'd argue that they are neither reals nor rationals. They are scientific numbers with no syntax to indicate "repeated" tails. Would be like saying that you want someone to represent 1/3 using 6 digits with no bar notation. Best you can do is "0.33333" and that just isn't the same. Moving it so that you have 6 digits with 2 being exponent, you are stuck with "3.333e-01". Which is just different still.
The way I like to frame it, and this will almost certainly not be mathematically rigorous, is that every number a float (as in, the formats defined in IEEE-754) can hold can be sufficiently described as at most a rational, though they cannot represent all rationals, and cannot represent anything "higher" than rationals. That's why I prefer to say they're representing rationals. It's in the sense that they're all representing some rational, not any arbitrary rational.
To do that would require infinite space. E.g. for one third, you'd need infinite binary digits (or even infinite decimal ones, as you say). It's just not how IEEE-754 floats work, as you mention.
This launched me into a research on "perfect numerical accuracy" a while back, and there I did find schemes where you store the numerator and the denominator separately, freeing you from this specific problem. It's a fun topic.
I don't tend to give much thought to real versus rational. Such that I still find it not that surprising to see people treat floats as reals. Especially since most languages make it hard to represent anything else. To that end, it will take me a bit to really internalize what you are saying here. I think I understand it.
That said, my favorite for the craziness of "old is new" is that the literal "1/3" works to represent a rational in Common Lisp. Indeed, I had originally thought that they had some specific constants for common fractions defined. Nope, they just support rational literals.
And I question if you need infinite space to represent repeated decimals. Strictly, you just need a way to indicate the repeating. No?
My point was strictly that we have "bar notation" in writing to show that 1.3 is not the same as 1.33 or 1.333 or 4/3. No matter how many 3s you put at the end. I don't know of any similar scheme in computers. I'm assuming it has been tried.
That is, yes, I know that 1/6 can be used to represent 0.1(6), but if you are already storing something in positional digits, there may have been a benefit to keeping it in positional digits? I'm assuming there was not, in fact, any benefit?
(We could think of other representations like 0.12'34 or something where the '34 indicates repeating digits. I've not seen that anywhere either, but it would be easy to implement.)
Actually getting the overbar, I wasn't too concerned with. Just noting that we have a way to do it on paper that doesn't require using ratios directly. Or infinite paper. :D
At any rate, this also got me thinking about how to do operations on repeated digits. I'm assuming I would have learned something like this years ago, but I don't remember it. At all. I vaguely remember it was awkward to realize that 0.(9) == 1. But, I don't recall playing with that too much. Is neat to see you should be able to make the general ideas work out just fine after you account for that? Just widen any repeating groups so that they are the same size, and then add. Reduce using the 9 rule.
It depends on your data structure, yes. You can also do the separate numerator / denominator thing, and I'm sure there are other ways too. Just that naively if you try representing it, that's when you need infinite space. Or if you do it the way IEEE-754 formats do.
Agreed that there are other ways, almost certainly. I was going with the assumption that we wanted to store positional values for that question.
That is, it is only when you assume that you have to write out all decimal digits that you get people writing silly things that computers do all of the time. "0.66666...7" is an easy example. Ironically, to me, is that in written assignments you likely would have gotten knocked off points for not writing 0.(6) where () means an overbar. You definitely would lose points for rounding at the end.
Tom7 has a good video about this: https://www.youtube.com/watch?v=5TFDG-y-EHs
Take realistic::Rational::fraction(1, 3) ie one third. Floats can't represent that, but we don't need a whole lot of space for it, we're just storing the numerator and denominator.
If we say we actually want f64, the 8 byte IEEE float, we get only a weak approximation, 6004799503160661/18014398509481984 because 3 doesn't go neatly into any power of 2.
Edited: An earlier version of this comment provided the 32-bit fraction 11184811/33554432 instead of the 64-bit one.