https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110045

--- Comment #7 from Frank J. T. Wojcik <gccbugs at elkpod dot com> ---
After playing with this a bit more, I was able to find a Generator which
produces a slightly wider bound, but still nowhere near 0x1.fffffep+127.
This also includes the requested change to SimpleGen.

#include <cstdio>
#include <cstdint>
#include <random>

#define MAXOFFSET 3

// Return 25-bit values centered around 0x1000000 (the halfway-point of all
// possible 25-bit outputs). Widening the Generator does not alter the
// program's output.
class SimpleGen {
 public:
    using result_type = uint32_t;
    result_type val, offset, ctr = 0;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return 0x1ffffff; }
    result_type operator()()           { offset = (ctr & 1) ?
                                            ((ctr / 2) / (2 * MAXOFFSET)) :
                                            ((ctr / 2) % (2 * MAXOFFSET));
                                         val = 0x1000000 + offset - MAXOFFSET;
                                         printf("\tG 0x%07x\n", val);
                                         ++ctr; return val; }
};

int main(void) {
    SimpleGen gen;
    std::normal_distribution<float> norm {0, 1};

    printf("min: %+f %a\nmax: %+f %a\n\n", norm.min(), norm.min(),
        norm.max(), norm.max());

    for (int i = 0; i < ((2 * MAXOFFSET) * (2 * MAXOFFSET - 1) * 2) ; i++) {
        float r = norm(gen);
        printf("%d %f %a\n", i, r, r);
    }
}

Build output:
$ g++-12.2 -Wall -Wextra -o normdist2 normdist2.cpp -fno-strict-aliasing
-fwrapv -fno-aggressive-loop-optimizations -fsanitize=undefined
$ echo $?
0

Actual outputs (excerpts only!):
min: -340282346638528859811704183484516925440.000000 -0x1.fffffep+127
max: +340282346638528859811704183484516925440.000000 0x1.fffffep+127

        G 0x1000000
        G 0x0ffffff
30 -8.157336 -0x1.0508e6p+3
31 0.000000 0x0p+0

        G 0x1000001
        G 0x0ffffff
32 -8.157336 -0x1.0508e6p+3
33 0.000000 0x0p+0

        G 0x0ffffff
        G 0x1000000
40 0.000000 0x0p+0
41 -8.157336 -0x1.0508e6p+3

        G 0x1000002
        G 0x1000000
42 0.000000 0x0p+0
43 7.985583 0x1.ff13ccp+2

        G 0x0ffffff
        G 0x1000001
48 0.000000 0x0p+0
49 -8.157336 -0x1.0508e6p+3

        G 0x1000002
        G 0x1000001
50 0.000000 0x0p+0
51 7.985583 0x1.ff13ccp+2

        G 0x1000000
        G 0x1000002
58 7.985583 0x1.ff13ccp+2
59 0.000000 0x0p+0

Expected outputs (excerpt only!):
min: -8.157336 -0x1.0508e6p+3
max: +7.985583 0x1.ff13ccp+2

Reply via email to