【问题标题】:Is there a way I can get a random number from 0 - 1 billion?有没有办法我可以从 0 到 10 亿得到一个随机数?
【发布时间】:2015-09-10 00:00:33
【问题描述】:

我现在不在乎效率。我只是在寻找一种可以生成从 0 到 10 亿的随机数的体面方法。我试过做 rand() * rand() 但它只给了我估计大于约 1000 万的数字。我希望范围更加分散。有人有什么建议吗?

【问题讨论】:

  • cplusplus.com/reference/random 比普通的 rand() 要好。例如mt19937_64 ...
  • MS VC++ 的 rand_s 范围为 0 到 UINT_MAX。
  • 顺便说一句,即使rand() * rand()足够大,结果也远不能均匀分布。
  • 请记住,库函数返回伪随机序列,而不是真正的随机数。对于后者,需要某种硬件设备。对于大多数用途(如娱乐游戏)来说,这是一个很小的区别,但是当在线扑克等有钱时,它是一个完全不同的游戏。见this

标签: c++ algorithm random


【解决方案1】:

当然,只需使用 C++ 的现代 <random> 工具:

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 1000000000);

for (int n=0; n<10; ++n)
    std::cout << dis(gen) << ' ';
std::cout << '\n';

(来自here,稍作修改以满足OP 的需求)将满足您的需求。

如果需要,还存在浮点值的模拟函数。


备注:万一您平台的int 不能容纳十亿,或者如果您需要更大的数字,您也可以使用更大的整数类型,如下所示:

std::uniform_int_distribution<std::int64_t> dis(1, 1000000000);

另请注意,此处介绍的播种 mt 不是最佳的;请参阅我的问题here 了解更多信息。

【讨论】:

  • 其实一个简单的long 就足够了,因为它可以保存至少20亿的值(不像int)。
  • @MSalters 是的,对于高达 2^31-1 的数字,即使 int 也可能足够好。我只是想强调它是模板化的,谁知道呢,也许这里有人需要高达 2^44 或类似的数字。
【解决方案2】:

10 亿略低于 2^30。如果不能直接生成 30 位数字,则生成两个 15 位数字,将一个左移 15 位,并与未移位的数字异或得到 30 位数字。

如果 30 位结果超过 10 亿,则将其丢弃并生成另一个 30 位数字。 2^30 = 1073741824,所以结果只会在大约 7% 的情况下太大。

【讨论】:

    【解决方案3】:

    随机序列/序列号(唯一且不可预测)

    如果只允许随机数具有唯一值。

    12345678900 72 12345678901 34. 12345678926 34. 12345678951 24. 12345678976 84. 12345678902 65. 12345678927 63. 12345678952 51.
    12345678977 67. 12345678903 09. 12345678928 11. 12345678953 19.
    12345678978 53. 12345678904 22. 12345678929 44. 12345678954 78.
    12345678979 04. 12345678905 21. 12345678930 85. 12345678955 76.
    12345678980 35. 12345678906 37. 12345678931 01. 12345678956 31. 12345678981 73. 12345678907 42. 12345678932 55. 12345678957 12. 12345678982 16. 12345678908 20. 12345678933 95. 12345678958 87. 12345678983 77. 12345678909 71. 12345678934 49. 12345678959 83. 12345678984 13. 12345678910 32. 12345678935 60. 12345678960 50. 12345678985 45. 12345678911 58. 12345678936 86. 12345678961 02. 12345678986 61. 12345678912 66. 12345678937 30. 12345678962 64. 12345678987 23. 12345678913 10. 12345678938 48. 12345678963 94. 12345678988 40. 12345678914 79. 12345678939 89. 12345678964 27. 12345678989 70. 12345678915 93. 12345678940 43. 12345678965 92. 12345678990 08. 12345678916 46. 12345678941 72. 12345678966 03. 12345678991 88. 12345678917 57. 12345678942 14. 12345678967 47. 12345678992 65. 12345678918 52. 12345678943 38. 12345678968 62.
    12345678993 17. 12345678919 15. 12345678944 75. 12345678969 80. 12345678994 54. 12345678920 41. 12345678945 07. 12345678970 18. 12345678995 28. 12345678921 62. 12345678946 25. 12345678971 58. 12345678996 74. 12345678922 26. 12345678947 69. 12345678972 43. 12345678997 29. 12345678923 91. 12345678948 82. 12345678973 59. 12345678998 33. 12345678924 05. 12345678949 56. 12345678974 81. 12345678999 78. 12345678925 36. 12345678950 68. 12345678975 90. 12345679000 06.

    这些是 101 个唯一的随机数

    每个数字由 13 位数字组成,其中前 11 位数字为序号,第 12 位和第 13 位数字共同构成一个随机数。 这最后两位数字将 11 位序列号转换为 13 位随机数。因此,当通过添加 1 或 2 位将序列号转换为随机数时,这种随机化不需要基于数学的算法。

    即使两位数是由基于数学的算法创建的,也可能有无数这样的算法可以创建两位数的随机数。

    因此,我的主张是,当 1、2 或 3 个随机创建的数字附加到序列号时,您会授予它随机性,并且此类随机序列号是不可预测的。

    因此,一个 11 位的 SHORTEST POSSIBLE 序列可以容纳十亿个不可预测的随机数,而一个只有 14 位的序列可以容纳一万亿个不可预测的随机数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多