gpt4 book ai didi

c - 截断时 float 舍入

转载 作者:行者123 更新时间:2023-12-03 08:37:48 30 4
gpt4 key购买 nike

这可能是 x86 FPU 专家的问题:

我正在尝试编写一个生成范围 [min,max] 内的随机浮点值的函数。问题是我的生成器算法(浮点 Mersenne Twister,如果你好奇的话)只返回 [1,2) 范围内的值 - 即,我想要一个包含上限,但我的“源”生成值是来自排他性上限。这里的问题是底层生成器返回一个 8 字节的 double ,但我只想要一个 4 字节的 float ,并且我使用的是最近的默认 FPU 舍入模式。

我想知道的是,在这种情况下,当 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 足以导致结果包含最大值。有关更多信息,请参阅 Crashworks 的回答。

最佳答案

SSE ops 将巧妙地改变此算法的行为,因为它们没有中间的 80 位表示形式——数学实际上是在 32 位或 64 位中完成的。好消息是,您可以通过简单地向 MSVC 指定/ARCH:SSE2 命令行选项来轻松测试它并查看它是否会改变您的结果,这将导致它使用 SSE 标量运算而不是普通浮点的 x87 FPU 指令数学。

我不确定整数边界周围的确切舍入行为是什么,但您可以测试以查看当 1.999.. 通过 eg

static uint64 OnePointNineRepeating = 0x3FF FFFFF FFFF FFFF // exponent 0 (biased to 1023), all 1 bits in mantissa
double asDouble = *(double *)(&OnePointNineRepeating);
float asFloat = asDouble;
return asFloat;

编辑,结果: 原始发布者运行了这个测试,发现截断后,1.99999 将四舍五入为 2,无论是否有/arch:SSE2。

关于c - 截断时 float 舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/644678/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com