当然,不是出于任何实际目的,但我尝试使用 Node 的加密模块生成一个安全的随机浮点数。本质上,如下:
var crypto = require('crypto');
var buf = crypto.randomBytes(4);
var float = buf.readFloatBE();
就以下测试而言,这在平均 0.40% 的情况下不起作用。我没有得到浮点数,而是得到NaN
.
var colors = require('colors');
var crypto = require('crypto');
var buf = new Buffer(4);
var fails = 0, tries = 100000;
var failures = [];
for (var i = 0; i < tries; i++) {
var num = crypto.randomBytes(4).readFloatBE(0);
try {
buf.writeFloatBE(num, 0);
} catch (e) {
fails++;
failures.push(buf.readUInt32BE(0).toString(2));
}
}
var percent = 100 * fails / tries;
if (fails)
percent = (percent.toFixed(2) + "%").red;
else
percent = '0.00%'.blue.bold;
console.log('Test ' + 'complete'.green.bold + ', ' + percent + ": " + fails + " / " + tries);
fails && console.log('Failed'.red + ' values:', failures.join(', '));
我猜这是由于 IEEE 单精度浮点数规范,但我不熟悉浮点数是如何存储为二进制的。
为什么会发生这种情况,确切地说,除了简单地生成浮点数直到我得到一个有效数字之外,我该如何规避这个问题?
编辑:查看过滤后的二进制数据时,它们似乎都遵循相同的模式:前 8 位都已设置。其他一切都是随机的。