这可能是 x86 FPU 专家的问题:
我正在尝试编写一个在 [min,max] 范围内生成随机浮点值的函数。问题是我的生成器算法(浮点 Mersenne Twister,如果你好奇的话)只返回 [1,2) 范围内的值 - 即,我想要一个包容性的上限,但我的“源”生成值是从一个排他的上限。这里的问题是底层生成器返回一个 8 字节的双精度,但我只想要一个 4 字节的浮点数,而且我使用的是默认的 FPU 舍入模式 Nearest。
我想知道的是,在这种情况下,截断本身是否会导致我的返回值在 FPU 内部 80 位值足够接近时包含最大值,或者我是否应该在将最大值乘以之前增加最大值的有效位[1,2) 中的中间随机数,或者我是否应该更改 FPU 模式。当然,或者任何其他想法。
这是我目前使用的代码,我确实验证了 1.0f 解析为 0x3f800000:
float MersenneFloat( float min, float max )
{
//genrand returns a double in [1,2)
const float random = (float)genrand_close1_open2();
//return in desired range
return min + ( random - 1.0f ) * (max - min);
}
如果它有所作为,这需要在 Win32 MSVC++ 和 Linux gcc 上工作。另外,使用任何版本的 SSE 优化会改变这个问题的答案吗?
编辑:答案是肯定的,在这种情况下,从 double 到 float 的截断足以导致结果包含 max。有关更多信息,请参阅 Crashworks 的答案。