1

也有类似的问题,但大多数都过于特定于语言。我正在寻找一个通用的解决方案。给定一些产生k随机字节和数字n的方法,我需要产生一个范围为1...n(包括)的随机数。

到目前为止我想出了什么:

  1. 要确定表示n所需的字节数,请计算

f(n):=ceiling(ln(n)/8ln(2))=ceiling(0.180337*ln(n))

  1. 为 0 索引字节 b[i]获取1...2^8f(n)范围内的随机数:

r:=0 for i=0 to k-1: r = r + b[i] * 2^(8*i) end for

  1. 无偏差地缩放到1...n :

    R(n,r) := ceiling(n * (r / 256^f(n)))

但我不确定这不会产生偏见或一些微妙的一次性错误。您能否检查一下这是否合理和/或提出改进建议?这是正确的方法吗?

在答案中,请假设没有可用的模块化位旋转操作,但您可以假设任意精度算术。(我在 Scheme 中编程。)

编辑:我的方法肯定有问题,因为在我的测试中掷骰子产生了一些 0 的情况!但是错误在哪里?

4

1 回答 1

1

这类似于如果您想从 0 到 1(含)的随机浮点数生成从 1 到 n 的数字,您会执行的操作。如果r是随机浮点数:

result = (r * n) + 1

如果您有任意精度算术,您可以r通过将您的 k 字节整数除以以字节表示的最大值k+ 1 来计算。

因此,如果您有 4 个字节87 6F BD 4A,并且n= 200:

((0x876FBd4A/0x100000000) * 200) + 1
于 2016-11-04T18:00:16.377 回答