rust-lang / rust-lang/libs-team
Bit-masks for the payload and signal bit of floating point NaN values
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 178
- Forks
- 28
- Avg merge
- 15m
- Merged PRs (30d)
- 1
Description
Proposal
Adding constants for masking the signal bit and payload of primitive NaNs.
Problem statement
Rust provides constants1 and functions for performing bitwise operations on floats but nan values lack the support that non-nan values have.
1The only one on stable is MANTISSA_DIGITS, but BITS, MANTISSA_MASK, EXPONENT_MASK, and SIGN_MASK are in the process of stabilization and a constant for the exponent bias has been proposed. See related work for links to the tracking issues/ACP.
Motivating examples or use cases
(Partially stolen from #779)
Some software uses NaN payloads as a compact metadata channel for values that are already represented as floating-point numbers. A common pattern is NaN-boxing or tagging schemes, where certain non-number cases are represented by quiet NaNs carrying payload bits.
Some possible motivating examples:
- A NaN payload might contain an application specific error code that encodes the reason why that value is a NaN.
- A NaN payload might contain the ID of the sensor that produced the NaN value
This proposal is not motivated by arithmetic semantics. Rust explicitly documents that arithmetic operations may choose NaN payloads non-deterministically from a constrained set, and that results do not generally preserve a chosen payload. NaN payoads should not be expected to survive any arithmetic operation.
The mask for the signal bit is less so intended to be used as a mask to read it, and more so in order to set the bit when generating a NaN in code. This would significantly reduce the risk of accidently setting the wrong bit, since accidently setting the exponent bit instead could can generate a bug that would be almost undetectable if the payload is never or incredibly unlikely to be 0.
Solution sketch
impl f32 {
/// <docs>
const PAYLOAD_MASK: u32 = 0x3FFFFF;
/// <docs>
const SIGNAL_BIT: u32 = 0x400000;
}
Alternatives
Using SIGNAL_MASK as the name of SIGNAL_BIT. This was not done since the SIGNAL_BIT constant is more intended for, and is expected to be more often used to set the signal bit rather than to mask it.
Links and related work
- functions for handling nan-payloads: #779
- bit masks for the parts of non-nan floats: https://github.com/rust-lang/rust/issues/154064
- bits constant for floats: https://github.com/rust-lang/rust/issues/151073
- exp bias constant: #784
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names no repository files or tests. Start by reviewing the linked related issues and the standard library feature lifecycle, then follow the libs-api team’s decision on the proposed constants and names. Done means the API proposal is approved and an implementation path, including validation coverage, is agreed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100