[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
https://bugs.llvm.org/show_bug.cgi?id=34932
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
compilation.
The reason for that is the rounding. The implementation does:
Then:
_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