【问题标题】:Generating random unsigned char values in C++在 C++ 中生成随机无符号字符值
【发布时间】:2012-04-17 16:33:06
【问题描述】:

我想知道如何生成随机无符号字符值。我的想法;
rand()%255; 因为无符号字符支持 0-255 之间。我想知道这种方法是否可以改进(或者它是最合法的方法)

【问题讨论】:

  • 定义“改进”。顺便说一句,您应该使用rand()%256
  • 其实我应该编辑“改进”我想知道这是否是正确的方式
  • 这是正确的方法。您也可以使用 C++11 中提供的随机实用程序,但这很有效。
  • 这还取决于您打算将这些值用于什么目的。它们是否将用作字符(例如,形成要打印或执行其他字符串操作的字符串)?还是您只是将它们用作无符号 8 位整数?
  • 我正在循环运行该函数以填充矩阵,并且大多数符号都是“?”。我已将 srand 设置为 'srand((unsigned)time(NULL));'

标签: c++ random unsigned-char


【解决方案1】:

如果你想坚持标准库,C++11 随机数库是最好的方法:

#include <random>

#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <climits>

int main() {
    std::random_device r;
    std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};

    auto rand = std::bind(std::uniform_int_distribution<>(0, UCHAR_MAX),
                          std::mt19937(seed));

    std::generate_n(std::ostream_iterator<int>(std::cout," "), 25, rand);
}

该库提供了一些统一的随机数引擎和适配器,与它们一起使用以生成各种分布。这里我们使用mt19937引擎(使用random_device作为种子(如果可能的话作为非确定性数据的来源)和seed_seq将足够的随机数据组合成适合填写mt19937内部状态的表格。然后我们适应mt19937 使用 uniform_int_distribution。默认情况下,此分布将产生均匀分布在其模板参数支持的范围内的数字,在本例中为 unsigned char。因此我们创建的函数对象将产生范围 [0 256 )。通过将 25 个值写入标准输出来演示其结果。

还有其他用途的分布,例如产生正态分布、模拟硬币翻转或从具有任意权重的集合中挑选物品(例如,从 3 个物品中挑选一个,其中第一个被选中 50% 的时间,第二个有 10% 的时间被选中,第 3 次则有 40% 的时间)。

针对不同的质量和性能特征提供了其他引擎。例如,如果您需要一个加密随机数生成器,如果您的实现提供了这种功能,则 random_device 可能会提供它。


Some 附加resources

【讨论】:

  • 请原谅我问了一个非常愚蠢的问题,但这种方法也适用于 g++ 对吧?
  • @rolandbishop 是的,最新版本的 gcc 实现了 C++11 随机库。我用 gcc 4.5.1 试过了
  • uniform_int_distribution&lt;unsigned char&gt; 在 Visual C++ 2013 中出现编译时错误,所以这个想法看起来不像是可移植的。
  • @Vitaliy 谢谢,我已经解决了这个问题。
【解决方案2】:

使用 random 库的 C++ 方式更简洁的方法是:

#include <random>

int myseed = 1234;

std::default_random_engine rng(myseed);
std::uniform_int_distribution<int> rng_dist(0, 255);
char mychar = static_cast<unsigned char>(rng_dist(rng));

【讨论】:

    【解决方案3】:

    而且您应该知道,就其输出的质量(随机性)而言,rand() 是广泛可用的随机数生成器中最差的一种。在基于 UNIX 的系统和其他一些系统上,random()lrand48() [和朋友们] 要好得多。为了速度,使用这些的最佳方法是如上面@Pida 所述,您只调用一次以获得一个单词的随机位。字长取决于您使用的随机数生成器。

    【讨论】:

      【解决方案4】:

      快很多会很简单

      unsigned char a = (unsigned char) rand();
      

      或者您甚至可以对生成的整数进行 4 次移位(在 32 位架构上),以减少对 rand() 的调用的四倍:

      int a = rand();
      unsigned char r1 = (unsigned char) a;
      unsigned char r2 = (unsigned char) a >> 8;
      unsigned char r3 = (unsigned char) a >> 16;
      unsigned char r4 = (unsigned char) a >> 24;
      

      或者类似的东西。

      【讨论】:

      • 既然 (unsigned char) 在那里,rand() 函数就不会越界了吧?
      • RAND_MAX 小于INT_MAX 的平台上(例如VC++,RAND_MAX32767),高位字节总是0
      • 问题仍然存在。事先简单检查是否是这种情况就可以了。
      【解决方案5】:

      你可以使用unsigned char n = (unsigned char)(rand() &amp; 0x00ff);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        • 2016-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-09
        相关资源
        最近更新 更多