Conversation
| @@ -5,11 +5,10 @@ use super::support::{FpResult, IntTy, Round, Status}; | |||
| use super::{CastFrom, CastInto, DFloat, Float, HFloat, MinInt}; | |||
|
|
|||
| // Placeholder so we can have `fmaf16` in the `Float` trait. | |||
There was a problem hiding this comment.
Is it really a placeholder if it (now) has implementation?
There was a problem hiding this comment.
Indeed, updated to a doc comment :)
40f4317 to
1c9cf79
Compare
This comment has been minimized.
This comment has been minimized.
0501cfc to
11e2b85
Compare
|
Baseline at 1909bf7: |
| } else { | ||
| rneg = mneg; | ||
| m64 + z64 | ||
| }; |
There was a problem hiding this comment.
At this point we have the result as a sign-magnitude fixed-point value that just needs rounding. The rest of this function might be a useful to factor out, and test independently. Something like
/// Rounds the value `n * 2^s` to `f16`
fn f16_from_u64_with_scale(n: u64, s: i32) -> f16And this could return
f16_from_u64_with_scale(r64, -40).copysign(/* from rneg */)| // Apply rounding from LSB and GRS bits | ||
| if r & 0b01000 != 0 && r & 0b10111 != 0 { | ||
| r += 0b1000; | ||
| } | ||
|
|
||
| if r & (1 << 15) != 0 { | ||
| // rounding overflowed to the next power | ||
| r >>= 1; | ||
| rexp += 1; | ||
| println!("round rexp: {rexp}"); | ||
| } | ||
| if r & (1 << 14) != 0 { | ||
| // ensure subnormals that rounded up get the exponent of 1 | ||
| rexp = rexp.max(1); | ||
| println!("sub rexp: {rexp}"); | ||
| } |
There was a problem hiding this comment.
A handy trick for doing the rounding: The effect of rounding a finite magnitude up is always just +1 to the bits of the float. If the mantissa had its maximum value, it carries into the exponent field but that still gives the correct value because the mantissa is then all zeroes.
Recreated from rust-lang/libm#419