-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Float16 optimal formatting #30862
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
Float16 optimal formatting #30862
Conversation
Extend SwiftDtoa to provide optimal formatting for Float16 and use that for `Float16.description` and `Float16.debugDescription`. Resolves rdar://61414101
@swift-ci Please test |
Build failed |
One interesting nit: When encoding NaNs, Swift sets the top payload bit if this is a regular "quiet" nan and the next-most-significant payload bit if this is a "signaling" NaN. For Float, Double, and Float80, SwiftDtoa uses the first of these to distinguish the two cases. However, that logic doesn't work for Float16. It appears that when converting Float16 to and from Float, the encoding for NaNs gets altered: the most significant payload bit is always set, and the next-most-significant is set for signaling NaNs. I've altered the SwiftDtoa logic accordingly for Float16 only. I'm not sure whether this encoding change should be considered a bug in our Float16 support or whether SwiftDtoa should be consistently keying on the second-most-significant bit instead of the first. |
For those interested in arcane details: Following gdtoa, SwiftDtoa produces the exact form for integral Float16 inputs, instead of the optimal (shortest) form. For example, the 0x1p13 formats as 8192.0 instead of the optimal 8190.0. Similarly, the maximum Float16 is 65504.0 (exact) instead of 65500.0 (optimal). Since these numbers are too small to render in exponential format, it just seems pointless to use the true optimal with trailing zeros when those same digits could be exact. |
Re sNaN: an unfortunate divergence from other types, mostly unavoidable, but not strictly a violation of IEEE 754. You have to either print a string that indicates signaling, or signal invalid. The conversion routine signals invalid, so there you are. |
Build failed |
@swift-ci Please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not try to finesse sNaN, otherwise this looks good.
Also mark the corresponding tests as `expectedFailure` until we can update the Float16 argument passing convention to not re-encode NaNs. Explanation: Swift's Float16 support passes Float16s by reencoding them to/from Float32. This works well for most purposes but incidentally loses the signaling marker from any NaN, with a side effect that the print code never actually sees a true sNaN. The earlier code here tried to detect sNaN in a different way, but that approach isn't guaranteed to work so we decided to make this code use the correct detection logic -- sNaN printing will just be broken until we can get a better argument passing convention.
I'm satisfied with this now. |
@swift-ci Please test and merge |
@swift-ci Please test and merge |
@swift-ci Please test and merge |
expectNaN("-snan(0xff)", -Float16(nan: 255, signaling: true)) | ||
expectNaN("snan(0xff)", Float16(bitPattern: 0x7dff)) | ||
} | ||
*/ | ||
expectEqual("nan", Float16.signalingNaN.description) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might need to drop these as well. Can we just check that the result contains "nan"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description
property always returns the constant string "nan" for any NaN, ignoring payload and flags. So the expectEqual
checks here are correct.
Only the debugDescription
contains any detail about nans.
@swift-ci Please test Linux |
Extend SwiftDtoa to provide optimal formatting for Float16 and use that for
Float16.description
andFloat16.debugDescription
.Resolves rdar://61414101