2012-12-04 36 views
4

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

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个不同的组)。我的实现看起来是否正确?

此外,我想知道,只是通过无效某些字节太大,我是否以任何方式倾斜分布?

+0

对不起,错过了你提供的范围。必须消失,所以我删除了我的答案,因为它没有处理范围。 –

+0

没关系,我喜欢你的阅读更多字节的想法,并将它们转换为更大的值。我可能会稍后使用它,但只是想确保这个基本实现不会破坏文件的任何随机性。 – chrissphinx

+0

32位整数由四个字节组成。因此,您可以安全地读取4个字节并将它们视为一个带符号的int。 –

回答

1

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

编程成功的关键是将您的任务分解为合适的子任务。快速规格:

  1. 添加一个函数来计算需要多少位来存储一个给定的数字
  2. 添加类读取并随机文件缓冲区的字节,并且有方法给你一些整数从文件中取出的位数(位0的其余部分)。
  3. 添加实际的方法,让您的随机数:
    • 计算结果的范围,并从中计算出所需
    • 循环得到位,增加下界,重试,如果结果超过的位数上限

备注第2步:第一个实现可以是相当粗糙的,你可以得到4个字节的整数,扔掉额外的比特,例如。稍后,您可以优化此类以保留未使用的位并在下次使用它们,以避免浪费随机位。由于获得真正好的随机位通常比较昂贵,因此这种优化可能值得为严肃使用而做。

位操作,例如参见这太问题: Java "Bit Shifting" Tutorial?

+0

好主意,有关如何保留未使用位的任何建议? – chrissphinx

+0

没有时间写完整的示例代码,但最简单的是添加成员变量'int lastReadByte;'和'int usedBitsInLastReadByte;'并且在一个方法中,您也可以使用temp变量'int unusedBits = 8 - this。usedBitsInLastReadByte;'然后休息只是位操作,并读取下一个字节,当所有8从当前字节被使用,请参阅我添加到答案本身的链接。 – hyde