5

I'm trying to use std::uniform_real_distribution<float>(a, b) to generate random floats, and I found a case where the output is equal to the upper limit b. According to: http://www.cplusplus.com/reference/random/uniform_real_distribution http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution this shouldn't happen.

With both gcc-4.9.2 and clang-3.5.0, the following crashes for me:

#include <iomanip>
#include <iostream>
#include <limits>
#include <random>

int main() {
    float a = 1.0f;
    float b = 1.001f;
    size_t seed = 293846;
    size_t n = 9830;
    std::mt19937 rg(seed);
    std::uniform_real_distribution< float > u(a, b);
    for (size_t i = 0; i < n; ++i) {
        float v = u(rg);
        if (not (v < b)) {
            std::cerr << "error: i=" << i
                      << " v=" << std::scientific << std::setprecision(std::numeric_limits< double >::max_digits10) << v
                      << " b=" << b << std::endl;
            abort();
        }
    }
}

The output I see is:

error: i=9829 v=1.00100004673004150e+00 b=1.00100004673004150e+00
Aborted (core dumped)

Is this a bug with the Standard Library? Am I missing something?

Edit. While not an exact duplicate, the issue raised in this question is indeed covered by the answer to the other question referenced here.

Most informative about the status of this issue is the LLVM bug thread here: https://llvm.org/bugs/show_bug.cgi?id=18767

Matei David
  • 2,322
  • 3
  • 23
  • 36

1 Answers1

0

While [rand.dist.uni.real] mandates the uniform distribution on the half-open interval of real numbers, it doesn't contain any language regarding how those should be rounded to floating point representations.

So from the information I could find, it may very well be legal (and required) for a conforming implementation to produce floating point numbers that compare equal to the upper bound.