<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - uniform_int_distribution may not be uniform in certain conditions" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D24267&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=-VTxmrETdHDeCRo2maMEEJ44pJzu080Zt4yIfZvK2H4&s=cDsA-un6ZkAJyQqcZdA3PPSzZMJ08VTf1c8FGeMsHv8&e=">24267</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>uniform_int_distribution may not be uniform in certain conditions
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libc++
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Other
          </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>sneves@dei.uc.pt
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu, mclow.lists@gmail.com
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The libc++ uniform_int_distribution algorithm works, essentially, by figuring
out the number of bits in the specified range [a, b], and then generating
numbers with that amount of bits until it hits one within range. It does this
by (details abridged)

  const _UIntType _Rp = __p.b() - __p.a() + _UIntType(1);
  const size_t _Dt = numeric_limits<_UIntType>::digits;
  size_t __w = _Dt - __clz(_Rp) - 1;
  if ((_Rp & (_UIntType(~0) >> (_Dt - __w))) != 0)
    ++__w;

Suppose _UIntType = uint64_t, a = 0, and b = 2^32. Suppose further that we are
working in a one's complement architecture (unlikely, I know). Then, if
negative zero is accepted as a non-trapped representation, uint64_t(~0) =
uint64_t(-0) = 0, and the number of bits will be one less than intended. In
particular, the value 2^32 will never be selected.

The fix to this is simple and painless: replace _UIntType(~0) by _UIntType(-1),
which is guaranteed to always convert correctly, even outside two's complement.
Or even better, std::numeric_limits<_UIntType>::max().</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>