fix: preserve non-finite values in Float.scaleB - #14690
Conversation
|
Mathlib CI status (docs):
|
|
Reference manual CI status:
|
This PR makes `Float.scaleB` and `Float32.scaleB` preserve infinities, NaN, and signed zero when scaling by exponents too large for the native `scalbn` interface. Handle boxed exponents using the limiting IEEE behavior and add regression coverage for both floating-point precisions.
|
You can add labels by writing a comment that just contains the name of the label (you can also delete the comment afterwards). You might need to edit your PR description back and forth for the check to notice the label change though. |
| public def main : IO Unit := do | ||
| IO.println ((Float.inf.scaleB hugeNegativeExponent).isInf) | ||
| IO.println (((-Float.inf).scaleB hugeNegativeExponent).isInf) | ||
| IO.println ((Float.nan.scaleB hugeNegativeExponent).isNaN) | ||
| IO.println (((-1.0 : Float).scaleB hugeNegativeExponent).toBits == (-0.0 : Float).toBits) | ||
| IO.println (((-0.0 : Float).scaleB hugePositiveExponent).toBits == (-0.0 : Float).toBits) | ||
| IO.println ((Float32.inf.scaleB hugeNegativeExponent).isInf) | ||
| IO.println (((-Float32.inf).scaleB hugeNegativeExponent).isInf) | ||
| IO.println ((Float32.nan.scaleB hugeNegativeExponent).isNaN) | ||
| IO.println (((-1.0 : Float32).scaleB hugeNegativeExponent).toBits == (-0.0 : Float32).toBits) | ||
| IO.println (((-0.0 : Float32).scaleB hugePositiveExponent).toBits == (-0.0 : Float32).toBits) |
There was a problem hiding this comment.
With the nature of this test, this should probably live in tests/elab instead and use #guard for testing (instead of IO.println).
Edit: Also, it might be more appropriate to use equality here for testing (which essentially compares toBits), i.e.
#guard Float.inf.scaleB hugeNegativeExponent = Float.inf
#guard (-Float.inf).scaleB hugeNegativeExponent = -Float.inf
#guard Float.nan.scaleB hugeNegativeExponent = Float.nan
#guard (-1.0 : Float).scaleB hugeNegativeExponent = -0.0
#guard (-0.0 : Float).scaleB hugeNegativeExponent = -0.0| @@ -0,0 +1,22 @@ | |||
| module | |||
|
|
|||
| import Init.Data.Float.Float32 | |||
There was a problem hiding this comment.
You don't need this import, declarations from Init are imported by default.
|
Thanks for the feedback, changes have been implemented and label is applied |
This PR makes
Float.scaleBandFloat32.scaleBpreserve infinities, NaN, and signed zero when scaling by extremely large exponents.Previously, the boxed-exponent path returned positive zero for every huge negative exponent, including non-finite inputs and negative finite values. Handle non-finite inputs and zero directly, and preserve the sign of underflowed finite values.
The PR also adds regression coverage for both precisions in
tests/elab/floatScaleB.lean.