hubert.reinterpretcast created this revision.
hubert.reinterpretcast added reviewers: mclow.lists, EricWF, jasonliu.
Herald added subscribers: ldionne, christof.

When a seed sequence would lead to having no non-zero significant bits in the 
initial state of a `mersenne_twister_engine`, the fallback is to flip the most 
significant bit of the first value that appears in the textual representation 
of the initial state.

rand.eng.mers describes this as setting the value to be 2 to the power of one 
less than w; the previous value encoded in the implementation, namely one less 
than "2 to the power of w", is replaced by the correct value in this patch.


Repository:
  rCXX libc++

https://reviews.llvm.org/D50736

Files:
  include/random
  test/libcxx/numerics/rand/rand.eng.mers/
  test/libcxx/numerics/rand/rand.eng.mers/cnstr_sseq_all_zero.pass.cpp

Index: test/libcxx/numerics/rand/rand.eng.mers/cnstr_sseq_all_zero.pass.cpp
===================================================================
--- /dev/null
+++ test/libcxx/numerics/rand/rand.eng.mers/cnstr_sseq_all_zero.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <random>
+
+// template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+//           UIntType a, size_t u, UIntType d, size_t s,
+//           UIntType b, size_t t,
+//           UIntType c, size_t l, UIntType f>
+// class mersenne_twister_engine;
+
+// template <class Sseq> explicit mersenne_twister_engine(Sseq &q);
+
+#include <random>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <initializer_list>
+
+struct all_zero_seed_seq {
+  typedef unsigned int result_type;
+
+  all_zero_seed_seq() {}
+
+  template <typename InputIterator>
+  all_zero_seed_seq(InputIterator, InputIterator) {}
+#if TEST_STD_VER >= 11
+  all_zero_seed_seq(std::initializer_list<result_type>) {}
+#endif
+
+  template <typename RandomAccessIterator>
+  void generate(RandomAccessIterator rb, RandomAccessIterator re) {
+    std::fill(rb, re, 0u);
+  }
+
+  std::size_t size() const { return 0u; }
+  template <typename OutputIterator> void param(OutputIterator) const {}
+};
+
+template <typename result_type, std::size_t word_size> void test(void) {
+  const std::size_t state_size = 1u;
+  const std::size_t shift_size = 1u;
+  const std::size_t tempering_l = word_size;
+
+  all_zero_seed_seq q;
+  std::mersenne_twister_engine<result_type, word_size, state_size,
+                               shift_size,
+                               0u,
+                               0x0,
+                               0u, 0x0, 0u, 0x0, 0u, 0x0,
+                               tempering_l,
+                               0u>
+      e(q);
+
+  const result_type Xneg1 = result_type(1) << (word_size - 1);
+  const result_type Y = Xneg1;
+  const result_type X0 = Xneg1 ^ (Y >> 1);
+  assert(e() == X0);
+}
+
+int main() {
+  // Test for k == 1: word_size <= 32.
+  test<unsigned short, 3u>();
+
+  // Test for k == 2: (32 < word_size <= 64).
+  test<unsigned long long, 33u>();
+}
Index: include/random
===================================================================
--- include/random
+++ include/random
@@ -2337,7 +2337,7 @@
         for (size_t __i = 1; __i < __n; ++__i)
             if (__x_[__i] != 0)
                 return;
-        __x_[0] = _Max;
+        __x_[0] = result_type(1) << (__w - 1);
     }
 }
 
@@ -2363,7 +2363,7 @@
         for (size_t __i = 1; __i < __n; ++__i)
             if (__x_[__i] != 0)
                 return;
-        __x_[0] = _Max;
+        __x_[0] = result_type(1) << (__w - 1);
     }
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to