将随机字节缩放到选定的整数范围

时间:2012-12-04 09:13:56

标签: java file random numbers

我有一个真随机字节的文件。我想要一个函数,通过从文件中取一个字节并对其进行缩放,返回给定范围内的随机整数。 (这是正确的词吗?)

public int getInt(int l, int h) throws IOException {
    int m = (h - l) + 1;            // number of ranges needed
    int r = 256 / m;                // size of byte range
    int x = (r * m) - 1;            // maximum allowable byte value
    int b;
    do {
        try {                       // get random byte from file
            b = ram.readUnsignedByte();
        } catch (EOFException e) {  // catch EOF, reset pointer
            b = 255; ram.seek(0);   // and set b to maximum value
        }                           // so test will fail.
    } while(b > x);                 // if byte is greater than
                                    // allowable value, loop.
    return (b / r) + l;             // return random integer
}                                   // within requested range

所以这是我的功能。我担心通过缩放来破坏文件中字节的真正随机性。我读到我需要丢弃任何超过允许最大值的数字(因此对于数字0-9,最大值是249,因为我只剩下7个值分配给10个不同的组)。我的实施看起来是否正确?

另外,我想知道,只是通过使某些太大的字节无效,我是否以任何方式扭曲了分布?

1 个答案:

答案 0 :(得分:1)

是的,为了避免偏见,你不能使用模数,你必须抛弃不在范围内的结果。

编程成功的关键是将您的任务分配到合适的子任务中。快速规范:

  1. 添加一个函数来计算存储给定数字所需的位数
  2. 添加一个从随机文件中读取和缓冲字节的类,并且有一个方法可以为您提供一个整数,该整数具有从文件中取出的一些位数(其余的位0)。
  3. 添加实际方法以获取随机数:
    • 计算结果范围,并从中计算所需的位数
    • 循环获取位,添加下限,如果结果超过上限
    • 则重试
  4. 关于第2步的注意事项:第一个实现可能非常粗糙,例如,您可以将4个字节作为整数并丢弃额外的位。稍后您可以优化此类以保留未使用的位并在下次使用它们,以避免浪费随机位。由于获得真正好的随机位通常有些昂贵,因此这种优化可能值得认真使用。

    对于位操作,请参阅此SO问题: Java "Bit Shifting" Tutorial?