Search code examples
randomfloating-pointd

Sampling from all possible floats in D


In the D programming language, the standard random (std.random) module provides a simple mechanism for generating a random number in some specified range.

auto a = uniform(0, 1024, gen);

What is the best way in D to sample from all possible floating point values?

For clarification, sampling from all possible 32-bit integers can be done as follows:

auto l = uniform!int(); // randomly selected int from all possible integers

Solution

  • Depends on the kind of distribution you want.

    A uniform distribution over all possible values could be done by generating a random ulong and then casting the bits into floating point. For T being float or double:

    union both { ulong input; T output; }
    both val;
    val.input = uniform!"[]"(ulong.min, ulong.max);
    return val.output;
    

    Since roughly half of the positive floating point numbers are between 0 and 1, this method will often give you numbers near zero.`It will also give you infinity and NaN values.

    Aside: This code should be fine with D, but would be undefined behavior in C/C++. Use memcpy there.

    If you prefer a uniform distribution over all possible numbers in floating point (equal probability for 0..1 and 1..2 etc), you need something like the normal uniform!double, which unfortunately does not work very well for large numbers. It also will not generate infinity or NaN. You could generate double numbers and convert them to float, but I have no answer for generating random large double numbers.