Неге uniform_int_distribution <uintmax_t> 62 биттық сандар үшін жұмыс істейді, бірақ 63 немесе 64 бит емес?

I'm having difficulty understanding why this code, an attempt to use the new header in C++11, is correctly generating random numbers in [0, 2**62 - 1] but not [0, 2**63 - 1] or [0, 2**64 - 1].

#include 
#include 
#include 
#include 
#include 

static std::mt19937 engine;//Mersenne twister MT19937

void print_n_random_bits (unsigned int n);

int main (void) {
  engine.seed(time(0));
  print_n_random_bits(64);
  print_n_random_bits(63);
  print_n_random_bits(62);
  return 0;
}

void print_n_random_bits (unsigned int n)
{
  uintmax_t max;

  if (n == 8 * sizeof(uintmax_t)) {
    max = 0;
  } else {
    max = 1;
    max <<= n;
  }
  --max;

  std::uniform_int_distribution distribution(0, max);

  std::cout << n << " bits, max: " << max << std::endl;
  std::cout << distribution(engine) << std::endl;
}

Енді тағы біраз қазу дұрыс мінез-құлыққа ие std :: mt19937_64 көрсетеді, бірақ маған түсіндіруге болады, неге 62-биттік нөмір үшін жұмыс істейтін 64 бит үшін жұмыс істемейді?

Edit: Sorry, I didn't even specify the problem. The problem is that for 63 and 64 bit max values, the output is consistently a number in the range [0, 2**32 - 1], e.g.:

% ./rand                       
64 bits, max: 18446744073709551615
1803260654
63 bits, max: 9223372036854775807
3178301365
62 bits, max: 4611686018427387903
2943926730538475327

% ./rand                                
64 bits, max: 18446744073709551615
1525658116
63 bits, max: 9223372036854775807
2093351390
62 bits, max: 4611686018427387903
1513326512211312260

% ./rand                                                       
64 bits, max: 18446744073709551615
884934896
63 bits, max: 9223372036854775807
683284805
62 bits, max: 4611686018427387903
2333288494897435595       

Edit 2: I'm using clang++ (Apple clang version 2.1 (tags/Apple/clang-163.7.1)) and "libc++". I can't easily test the above with GCC as my version doesn't have c++0x support.

20
Мүмкін оны жаман сәтте қарастырайық :)
қосылды автор Dani, көзі
GCC 4.6.1 бірге, барлық үш сынақ (62/63/64 биттер) 64 биттік мәндерді қайтарады.
қосылды автор Mike Seymour, көзі
GCC4.5.1 бірге, барлық үш сынақ (62/63/64 биттер) 32-биттік мәндерді қайтарады. Ideone.com/3GZ9S
қосылды автор interjay, көзі
Мұның бәрі күтпеген нәрсе? Яғни, сізді күтілетін нәтижелерден ерекшеленетін нəтижелерді қалай дәлелдейді?
қосылды автор andand, көзі
Сондай-ақ, қандай стандартты кітапхананы қолданасыз?
қосылды автор Fanael, көзі

2 жауаптар

Libc ++ ішіндегі қатені таптыңыз. Рахмет!

Мен келесі түзетуді 143104 шлюзді қайта қарап шығардым:

Index: include/algorithm
===================================================================
--- include/algorithm   (revision 143102)
+++ include/algorithm   (working copy)
@@ -2548,7 +2548,7 @@
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y0_);
-        if (__w0_ < _EDt)
+        if (__w0_ < _WDt)
             _S <<= __w0_;
         else
             _S = 0;
@@ -2561,7 +2561,7 @@
         {
             __u = __e_() - _Engine::min();
         } while (__u >= __y1_);
-        if (__w0_ < _EDt - 1)
+        if (__w0_ < _WDt - 1)
             _S <<= __w0_ + 1;
         else
             _S = 0;

Бұл түзету үшін екілік libc ++. Dylib.

23
қосылды
Мен білмеймін. Алгоритм тәуелсіз_bits_engine үшін стандартты спецификацияда көрсетілген.
қосылды автор Howard Hinnant, көзі
Libc ++-де қолданылған бұл алгоритм туралы белгілі бір атау бар ма?
қосылды автор Mateusz Drost, көзі
Уа, тез жұмыс! Ховардқа рахмет.
қосылды автор Qchmqs, көзі

std :: mt19937 - бұл 32 биттік нұсқасы болғандықтан, ең алдымен, бұл келесі бит жасаған кезде қандай биттердің жасайтыны және оның «жұмыс кеңістігінде» маңызы жоқ деген болжамдар жасайды. Бұл кейінгі соңғы екі биты қоса алатын сандарды генерациялау кезінде толып кетуге әкеледі. 32-биттік қозғалтқыштағы 2 ** 32 - 1 -дан жоғары максималды сандармен шынайы тарату шынымен бірдей болмайтындығына күмәнданамын.

0
қосылды
Егер mt19937 32-дәрежелі сандарды қайтарса, uniform_int_distribution 62/63/64-bit нөмірлерін жасау үшін бірнеше рет қоңырау шалмауы керек?
қосылды автор interjay, көзі
Бұл туралы сенімді емес. Қысқаша зерттеулер 1,000,000 генерацияланған бүтін санаттарға негізделген тарату коды 2 ** 62 - 1 ең көп болатын бірдей немесе ең жақын-лас-қарақұмық болып табылатынын көрсетеді.
қосылды автор Qchmqs, көзі