[llvm-bugs] [Bug 34932] New: std::generate_canonical can produce 1.0

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Oct 12 14:34:05 PDT 2017


            Bug ID: 34932
           Summary: std::generate_canonical can produce 1.0
           Product: libc++
           Version: 5.0
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: thiago at kde.org
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

Take the following 64-bit generator:

struct G
    typedef uint64_t result_type;
    result_type operator()() { return ~0ULL; }
    static constexpr result_type min() { return
(std::numeric_limits<result_type>::min)(); }
    static constexpr result_type max() { return
(std::numeric_limits<result_type>::max)(); }

When used with std::generate_canonical, like so:

double generateDouble3(uint64_t x)
    G rd;
    return std::generate_canonical<double, 64>(rd);

It will produce a result of exact 1.0. See https://godbolt.org/g/A1Wfhx for

The reason for that is the rounding. The implementation does:


    _RealType __base = _Rp;  // 2.0 ^ 64
    _RealType _Sp = __g() - _URNG::min();
    for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp) // does not execute
(__k == 1)
        _Sp += (__g() - _URNG::min()) * __base;
    return _Sp / __base;

When the input is in the range 0xfffffffffffff000 to 0xffffffffffffffff, the
division  the last line is an exact result of (1.0L - 0x1.p-53) to (1.0L -
0x1.p-64), but those round up to 1.0.

libstdc++ catches this case and returns std::nextafter<_RealType>(1, 0) [the
largest _RealType smaller than 1].

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20171012/32de7e99/attachment-0001.html>

More information about the llvm-bugs mailing list