There doesn't seem to exist an easy way to get the exponent and mantissa from a f32. The only way seems to be to use f32::to_bits and parse the bits.
And vice-versa, there doesn't seem to exist a direct way to convert exponent+mantissa to f32, except messing with f32::from_bits, or using mantissa * 2.0f32.powi(exponent) (but multiplication and powi seem like an overkill for this, and the formula risks underflow in the power of 2).
These would have been useful to me when I was implementing my bignum <-> floating point conversions, and now they'd be useful to me to fix the div_euclid bug in std.
I’d be in favor of giving the Nan variant a NonZero<u32> payload argument so that this type has the capability to losslessly round-trip with any f32 value.
Also, it probably makes sense to provide a fallible version of from_repr which checks for overflow in the various fields.
———
Edit: For round-tripping, it needs to differentiate between +0 and -0 as well, which the current version isn’t equipped for.
Edit: Another option would be to keep mantissa as i32 in this version also, so that from_repr can still be used to convert from a signed mantissa by just using the Positive sign even if the number is negative...
Separating the sign from the mantissa is inconvenient because it requires two cases to deal with the mantissa where we really usually just want a signed mantissa.
That looks reasonable; my biggest concern would be confusion about how conversions handle a sign bit that disagrees with the given mantissa-- Does a Negative sign bit:
I doodled some code to work on float parts a while ago, cleaned it up and pushed to GitHub thanks to this thread: flotsam. The extension trait might be too invasive as it is now, adding too much clutter to the float types when it's in scope, but YMMV.
frexp and ldexp would go some way towards it, but for my two practical use cases (one of which is fixing f32::div_euclid), I'd want a i32, so I'd have to convert it anyway.
I've used ldexp a few times before, and every time I used it, I converted an integer to floating point first in order to pass it into ldexp.
It'd also be nice to have the special cases (infinities and NaN) as enum variants, rather than having to deal with them by if checks for special values. The frexp interface is very C-style because C lacks enums, so it returns some arbitrary values for these.
This could also be useful as a teaching tool and for studying behavior of floating point functions. Whenever people ask questions about floating point, one could use this to see exactly what's going on inside rather than using some external calculators or converters. For this, it would be nice to see an integer mantissa, so that you know (mantissa + 1) is the next representable number.