首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么mt19937的STD实现具有双倍的boost版本?

为什么mt19937的STD实现具有双倍的boost版本?
EN

Stack Overflow用户
提问于 2020-08-26 15:56:10
回答 1查看 374关注 0票数 3

我有一个简单的C++程序,具有意想不到的输出:

代码语言:javascript
复制
#include<random>
#include<iostream>
#include "boost/random/mersenne_twister.hpp"
#include "boost/random/uniform_int_distribution.hpp"

int main(){
    std::cout << sizeof(std::mt19937) << std::endl;
    std::cout << sizeof(std::mt19937_64) << std::endl;
    std::cout << sizeof(boost::random::mt19937) << std::endl;
    std::cout << sizeof(boost::random::mt19937_64) << std::endl;
}

clang和gcc的产量

5000 二五零四 二五零四 二五零四

我发现有趣的是,mt19937(32位1)的大量标准实现大约是boost版本的2倍,而64位的则完全匹配。

由于MT使用了大量的空间,这并不是一个很小的区别。

同样奇怪的是,严格指定的算法的实现会有如此不同的大小,我们不是在谈论std::string,其中实现者可能选择不同的SSO缓冲区大小.

我最好的猜测是boost要么有一个bug,要么它实现了一些稍微不同的mt19937版本,但维基百科说,这表明boost可能是正确的:

相对较大的状态缓冲器,2.5 KiB,

编辑: boost和std版本似乎都是满足要求的第1000生成值是4123659995,所以在boost中似乎没有bug。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-26 16:25:39

这是标准定义:

代码语言:javascript
复制
mersenne_twister_engine<
    uint_fast32_t, // element of the buffer
    32,
    624,           // size of the buffer
    397, 31,
    0x9908b0df, 11,
    0xffffffff, 7,
    0x9d2c5680, 15,
    0xefc60000, 18, 1812433253>

问题是GNU选择std::uint_fast32_t是64位系统上的64位类型(这是一个好的还是坏的选择是单独的讨论)。因此,如果缓冲区包含32位整数,则缓冲区的大小是预期的两倍。

这是Boost的定义:

代码语言:javascript
复制
mersenne_twister_engine<
    uint32_t,
    32,
    624,
    397, 31,
    0x9908b0df, 11,
    0xffffffff, 7,
    0x9d2c5680, 15,
    0xefc60000, 18, 1812433253>

它是相同的,除了使用固定宽度的元素,在所有系统上都是相同的。

您可以直接使用std::mersenne_twister_enginestd::uint_least32_t元素来解决这个问题。使用这个别名比固定别名更可取,因为它需要在所有系统上得到支持。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63601328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档