-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement fmt::Binary for f32 and f64 #49066
Conversation
r? @bluss (rust_highfive has picked a reviewer for you, use r? to override) |
If we do this, there should also be matching |
Sure, I can add those now to give a more complete picture when reviewing. |
It makes more sense to actually represent the number in binary, instead of its bits. If I want to show its bits, I'll explicitly call |
I have some sympathy for that position, but note that AFAIK we don't currently have any precedent for how to render a binary float in base 2. For hex there is a relatively established syntax (used in Java for example), but I've never seen anything for base 2. |
@clarcharr: although I can understand that viewpoint, I don't think it's the natural way to display a IEEE 754 floating point number (as opposed to, say, |
@rkruppe I mean, there isn't precedent for it, but considering how the exponent for hex literals is a power of two, it seems very logical to do similarly for binary literals. I can't imagine it being implemented any other way, although having a standard hex format print for I personally vote to print the actual float for binary, octal, and hex formatting. That said, it might make more sense to have an RFC for adding that to the syntax first... Either way, considering how this impl would be insta-stable, I'm not comfortable having this be the default when |
@varkor oh, I didn't know that. In that case, it makes sense to make the binary impl print the bits. I still stand for octal and hex however. |
@clarcharr
Do you mean printing the number in base 8 and 16, as opposed to printing the IEEE 754 encoding as |
@clarcharr: arguments for preferring mathematical or bitwise representations could have been made either way originally (I'm not sure what the original motivations were), but currently integers are formatted bitwise with |
I'm with @clarcharr on this one; I see no value in printing the bitwise representation when it is easy to About consistency with signed integers, it is true that signed integers are formatted bitwise, but at least they consist of a single field where the meaning is much closer to an unsigned integer than the meaning of bits in floating-point numbers. IEEE754 numbers consist of three separate fields which can also complicate things: when you need to examine the bit representation, it almost always makes sense to separate the three fields, and they don't even lie on hex-digit boundaries, so printing the fields independently in hex is very different from printing the whole bitwise representation in hex. And if consistency with signed integers is cited, then the commit should not include a width and zero-padding; Also, printing the bitwise representation is more useful in debugging than in displaying; and |
I agree here: unless there's a unanimous opinion about how to best format floating points in hex, I'd rather leave them for now. But perhaps @rkruppe had thoughts here?
Honestly, I think this is a mistake in the design of the
Why do you say this? Printing the 2's-complement representation of an integer seems more like |
I am also leaning towards not implementing |
Out of curiosity, @clarcharr, do you have any concrete examples of when you've wanted to print the decimal expansion of a floating-point number before? Just wondering whether it's just what you would expect the behaviour to be in this case, or whether the other behaviour is useful. |
I also think that the current behaviour is a mistake. My intention was not to say that the floats should be printed in less than 32/64 bits, but that the consistency argument is flawed, especially when considering that floats are very different from integers.
I always had the impression that all the formatting traits except In conclusion, I'm wary of implementing |
@varkor The US' outdated system of measurement often measures in binary (eg. 5/16 inches) and while I've never personally written Rust code to deal with this it's not an unusual representation to try and figure out what 0.2 is in a binary-float expansion. In terms of debugging, I personally find a binary float representation to be more fruitful than a raw-bit version. Knowing that
instead of:
Is honestly less useful to me. I can read the latter as And, if I want to construct the actual IEEE754 representation, I can encode the sign, exponent, and mantissa back quite easily. Thinking this over again, this in fact doesn't go against the fact that |
Readability of the components is a good point. What do you think about a space or underscore separated format, e.g. |
I hacked a couple of quick wrappers (playground link) for the two possibilities. I only implemented |
Yeah, not a very hard choice; the expansion looks way better than the raw version. |
An expansion is not helpful for my use cases (which render the aesthetics moot), so I'll just close the PR, as if there's not general agreement, there's not strong motivation to settle this question here. While I'd prefer to see some more examples of where a binary expansion is desirable, you're right in that it's not difficult to print the bitwise representation without this implementation, so it's not pressing. |
I often find it useful to print
f32
andf64
in their binary formats when doing floating point analysis or bit manipulations (e.g. in #48622) and I'm definitely not the only one. Printing their binary representation seems like sensible behaviour forfmt::Binary
.I've opted to print fixed-width (i.e. 32 bits for
f32
and 64 bits forf64
) because this seems to make the most sense for the primary use cases of printing the floating-point representation, where the bit ranges are very much relevant to the values, unlike for integers.