<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - std::generate_canonical can produce 1.0"
href="https://bugs.llvm.org/show_bug.cgi?id=34932">34932</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>std::generate_canonical can produce 1.0
</td>
</tr>
<tr>
<th>Product</th>
<td>libc++
</td>
</tr>
<tr>
<th>Version</th>
<td>5.0
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>All Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>thiago@kde.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org, mclow.lists@gmail.com
</td>
</tr></table>
<p>
<div>
<pre>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 <a href="https://godbolt.org/g/A1Wfhx">https://godbolt.org/g/A1Wfhx</a> 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].</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>