Skip to content

Generating all floating-point numbers #1816

Description

@vigna

While the division strategy used by this crate (take 53 bits, divide by 2⁵³) provides 2⁵³ equispaced points in [0 . . 1), it is unable to generate most of the possible floating-point values—in particular, values closer to zero than 1/ 2⁵³.

This is a known problem—conversion to floating point has been a sore point in all major programming languages for a long time (Go used 63 bits, and old Java versions used 54, resulting in a nonuniform distribution, for example).

While the definition of uniformity induced by the definition above is reasonable (the probability of each number is proportional to the empty space around it), it is possible to generate all floating-point numbers (including subnormals) with a probability proportional to the space around it (that should be formalized in terms of ULP, but I'm keeping it simple). For ordinary computation this is kinda hair splitting, but for some computations (e.g., generating normal deviates) having a more accurate representation around zero is important.

After some discussion with the most known experts in the field (Nima Badizadegan, Frédéric Goualard, and Taylor R. Campbell) I put together a crate comparing the three best techniques I could put my hands on.

I think rank should provide (maybe as a subcrate?) at least one method providing full floating-point generation for demanding scientific environments. I believe that the for the standard, off-the-shelf case 53-bit division is ok, but Rust is a technically very precise language, and in this moment its handling of floating-point generation could be improved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions