如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度
How to convert random uint64_t to random double in range (0, 1) using bit wise operations
我能达到的最好的结果是这个(它给出的结果在 0 ~ 0.5 之间(:
uint64_t const FRACTION_MASK = 0x1fffffffffffffull;
uint64_t const EXPONENT_BITS = 0x3fc0000000000000ull;
double to01(uint64_t i) {
i = (i & FRACTION_MASK) | EXPONENT_BITS;
return reinterpret_cast<double&>(i);
}
我反复试验并错误地找出这些神奇的数字。我什至不知道这个是否可以生成双精度可以在 0 到 0.5 之间代表的所有值。
由于双精度数的编码方式,很难直接生成范围(0,1(中的良好随机数,但很容易在范围[1,2([@GemTaylor]中生成一个随机数。
double to_01(uint64_t i)
{
constexpr uint64_t mask1 = 0x3FF0000000000000ULL;
constexpr uint64_t mask2 = 0x3FFFFFFFFFFFFFFFULL;
const uint64_t to_12 = (i | mask1) & mask2;
double d;
memcpy(&d, &to_12, 8);
return d - 1;
}
请注意,并非所有i
位都用于生成结果。另请注意,此函数仅适用于 64 位 IEEE-754 浮点数 [@geza]。
根据我收集的内容,仅从您要将uint_64
位映射到double
位的问题判断,以便您的double
介于 [0, 1] 之间
双精度(64 位(表示形式为
-1S × (1.0 + 0.M( × 2E 偏置(偏置为 1023(
符号 S 的位,马蒂萨的 52 位和指数的 11 位。
前double
是有符号的,因此无法映射符号位,因为您需要double
>0.0。 其次,我们不能超过 E 偏差>1022,否则我们将得到超过 1.0 的值double
.
因此,在 [0, 1] 之间映射uint_64一倍的掩码为
0 01111111110 1111111111111111111111111111111111111111111111111111 在十六进制中
0x3FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF因此代码
uint64_t const MASK = 0x3FEFFFFFFFFFFFFFull;
double to01(uint64_t i) {
i = (i & MASK);
return reinterpret_cast<double&>(i);
}
应该做这个伎俩。使用这种方法,您已经使用了 61 位中的 64 位uint_64。
但请注意:如果您的uint_64
发生器均匀超过 [0, uint64_t_max] 使用to01
获得的发生器将不会均匀超过 [0,1] !
这是我使用的 我移位 12 得到 52 位 I 或 1 以便我只得到奇数值,这样可以避免返回 0 然后在返回时减去 1.0
如果你是整数的源是均匀分布的 您的结果将均匀分布
double convert_uint64_to_double(uint64_t value)
{
uint64_t u64 = 0x3FF0000000000000ULL | ((value >> 12) | 1) ;
return *(double*)&u64 - 1.0;
}
double convert_uint32_to_double(uint32_t value)
{
uint64_t u64 = 0x3FF0000000000000ULL | (((uint64_t(value) << 1) | 1) << 19);
return *(double*)&u64 - 1.0;
}
- 如何使用按位运算将随机uint64_t转换为范围 (0, 1) 的随机双精度
- 如何自定义设置随机的范围?
- 随机选择 2 个不在范围内的整数
- 随机整数仍在生成低于或高于范围的数字?
- 范围 - v3 中的随机播放操作
- 有没有有效的方法可以从现在开始生成从范围到 10 天的随机date_time
- C 使用单个生成器从多个范围内提升随机INT
- 编写一个程序,该程序在0-99范围内生成10000个随机整数,并从随机数据中产生直方图
- C++随机访问迭代器超出范围
- 需要在指定范围内生成一个随机整数
- MFC对话框成员变量的随机崩溃不在范围中
- 特征矩阵库在给定范围内用随机浮点值填充矩阵
- 在多次迭代中创建随机大小(在特定范围内)的数组
- 在数组中随机生成固定范围的数字,在该 2D 数组中没有重复行
- 在C++中实现随机预言机(输出在范围内是随机的,但对于相同的输入输出是相同的)
- 从用户输入的范围中为不同的类创建不同的随机x,y值
- 如何用范围内的随机值填充数组?(可以复制.)
- 为什么标准不允许 std::for_each 对无效的随机访问迭代器范围有明确定义的行为?
- 这是从容器中获取随机元素的OK范围的方法吗
- 从随机范围中排除一个数字