首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现随机浮点函数,使其不会丢失熵?(PHP)

如何实现随机浮点函数,使其不会丢失熵?(PHP)
EN

Stack Overflow用户
提问于 2010-09-11 23:36:35
回答 1查看 644关注 0票数 8

我尝试使用从/dev/urandom获得的字节生成随机浮点数。目前,我最好的想法是让平台精确度达到如下所示:

代码语言:javascript
复制
$maximumPrecision = strlen('' . 1/3) - 2;

然后按照$maximumPrecision告诉我们的次数,在一个循环中构造一个0-9的字符串。例如,如果精度是12,我将生成12个随机数并将它们连接起来。我认为这是一个丑陋的想法。

更新:这有意义吗?

代码语言:javascript
复制
$bytes =getRandomBytes(7); // Just a function that returns random bytes.
$bytes[6] = $bytes[6] & chr(15); // Get rid off the other half
$bytes .= chr(0); // Add a null byte

$parts = unpack('V2', $bytes);

$number = $parts[1] + pow(2.0, 32) * $parts[2];
$number /= pow(2.0, 52);
EN

回答 1

Stack Overflow用户

发布于 2010-09-12 01:48:10

这里的问题是,IEEE double precision number是根据以2为底的指数定义的:

代码语言:javascript
复制
n = 2^exponent * 1.mantissa

因为你想要一个指数-1,并且没有整数n来表示2^n = 0.1,所以它变得很复杂。

这将生成一个介于1和2之间的数字。您可以减去1,但如果这样做,您将损失极少量的熵(KennyTM的答案产生一个在该范围内的数字,并使用所有熵--此答案尝试直接创建表示法):

代码语言:javascript
复制
$source = fopen("/dev/urandom", "rb");

//build big-endian double
//take only 32 bits because of 32-bit platforms
$byte_batch_1 = fread($source, 4); //32-bit
$byte_batch_2 = fread($source, 4); //32-bit, we only need 20

$offset = (1 << 10) -1;

$first_word = unpack("N", $byte_batch_2);
$first_word = reset($first_word);
$first_word &= 0xFFFFF; //leave only 20 lower bits
$first_word |= $offset << 20;

$str = pack("N", $first_word) . $byte_batch_1;

//convert to little endian if necessary
if (pack('s', 1) == "\x01\x00") { //little-endian
    $str = strrev($str);
}

$float = unpack("d", $str);
$float = reset($float);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3691569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档