You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[libc++] mersenne_twister_engine compares equal after a stream round trip but produces a different sequence #242467
Since #222700, a std::mt19937 that is written with operator<< and read back with operator>> compares equal to the original but produces a different sequence, unless the original had produced a multiple of 624 values.
#include<iostream>
#include<random>
#include<sstream>intmain() {
std::mt19937 a(7), b;
(void)a(); // any number of draws that is not a multiple of 624
std::stringstream s; s << a; s >> b;
std::cout << "a == b: " << (a == b) << '\n';
int i = 0; while (i < 1000 && a() == b()) ++i;
std::cout << "first differing output: " << (i < 1000 ? i : -1) << '\n';
}
clang++ -std=c++17 -stdlib=libc++ -O1, libc++ trunk as of 2026-11-13 (_LIBCPP_VERSION 240000, Compiler Explorer x86-64 clang trunk):
a == b: 1
first differing output: 623
libc++ from LLVM 23.1, libstdc++ and the MSVC STL print first differing output: -1. After k draws the read-back engine differs at output 624 - k % 624 (k = 5: 619, k = 1000: 248).
x == y means the two engines have the same state ([rand.req.eng]), and engines with the same state produce the same sequence, so a == b cannot be true here. The written representation also changed: [rand.eng.mers]/5 says it consists of X(i-n), ..., X(i-1), so for std::mt19937 g(7); std::cout << g; the first value is the seed. Trunk prints 2022286329 1444425037 ...; LLVM 23.1, libstdc++ and the MSVC STL print 7 4097098180 ....
Since #222700 the state array holds values that are already twisted. operator<< writes that array starting at __i_, and operator>> stores it back with __i_ = 0. After 624 - k outputs the restored engine returns again the k values that the original returned before it was written, and then twists a rotated array. Programs that save and restore an engine with << and >> get a different sequence after the restore. release/23.x does not contain e364b9d, so this is in trunk only.
I don't have a fix: writing X(i-n), ..., X(i-1) from the twisted storage needs a decision on how the state is kept.
Assisted-by: Claude (claude-opus-5-5). I reviewed this text.
Activity