diff options
| author | Trevor Gross <tmgross@umich.edu> | 2025-04-16 18:43:25 +0000 |
|---|---|---|
| committer | Trevor Gross <t.gross35@gmail.com> | 2025-04-16 15:28:10 -0500 |
| commit | e4d716c84801d1d91d473aaa28692f595f352b34 (patch) | |
| tree | 9242e1f01022c673c15348b86824ee7d43f03ab8 | |
| parent | 14ab2453f235ce66074d54e4040ce06febfe54f4 (diff) | |
| download | rust-e4d716c84801d1d91d473aaa28692f595f352b34.tar.gz rust-e4d716c84801d1d91d473aaa28692f595f352b34.zip | |
fmod: Correct the normalization of subnormals
Discussed at [1], there was an off-by-one mistake when converting from the loop routine to using `leading_zeros` for normalization. Currently, using `EXP_BITS` has the effect that `ix` after the branch has its MSB _one bit to the left_ of the implicit bit's position, whereas a shift by `EXP_BITS + 1` ensures that the MSB is exactly at the implicit bit's position, matching what is done for normals (where the implicit bit is set to be explicit). This doesn't seem to have any effect in our implementation since the failing test cases from [1] appear to still have correct results. Since the result of using `EXP_BITS + 1` is more consistent with what is done for normals, apply this here. [1]: https://github.com/rust-lang/libm/pull/469#discussion_r2012473920
| -rw-r--r-- | library/compiler-builtins/libm/src/math/generic/fmod.rs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/library/compiler-builtins/libm/src/math/generic/fmod.rs b/library/compiler-builtins/libm/src/math/generic/fmod.rs index c74b593d559..cd23350ea3a 100644 --- a/library/compiler-builtins/libm/src/math/generic/fmod.rs +++ b/library/compiler-builtins/libm/src/math/generic/fmod.rs @@ -26,7 +26,7 @@ pub fn fmod<F: Float>(x: F, y: F) -> F { /* normalize x and y */ if ex == 0 { - let i = ix << F::EXP_BITS; + let i = ix << (F::EXP_BITS + 1); ex -= i.leading_zeros() as i32; ix <<= -ex + 1; } else { @@ -35,7 +35,7 @@ pub fn fmod<F: Float>(x: F, y: F) -> F { } if ey == 0 { - let i = iy << F::EXP_BITS; + let i = iy << (F::EXP_BITS + 1); ey -= i.leading_zeros() as i32; iy <<= -ey + 1; } else { |
