我有一个输入浮点值,它是0.0f
当将此值乘以更大的范围时,自然会降低浮点精度,这意味着该值最终可能超出等效范围。
例如,如果我从一个值开始,例如:
0.99999983534521f
然后乘以100,我得到:
100.000000000000f
哪个很好,但是如何将浮点表示形式减小为最接近的浮点值,但仍小于100?
我发现了这个小技巧:
union test
{
int integer;
float floating;
};
test value;
value.floating = 1.0f;
printf("%x\n", value.integer);
然后,我将那个十六进制值减去一个十六进制数字,然后像下面这样显式设置:
unsigned int almost_one = 0x3f7fffff;
float value = 1.0f;
if (value >= 1.0f) std::memcpy(&value, &almost_one, sizeof(float));
这对于此特定值效果很好,但是我可以使用更通用的方法吗?
我希望有一个我不知道的魔术指令可以用来实现这一目标!
编辑:很好的答案在这里,std::nextafter看起来像我想要的。不幸的是我还不能使用C++ 11数学库,所以这对我不起作用。为了节省复杂的事情,我将用C++ 11标记这个问题,并在下面接受Mike的回答。
我对C++ 03提出了一个新问题:Alternative to C++11's std::nextafter and std::nexttoward for C++03?
最佳答案
如果您具有C++ 11(或C99)标准库,则std::nextafter(value, 0.0f)
中的<cmath>
(或nextafter
中的<math.h>
)将为您提供小于value
的最大可表示值。
它在第一个参数之后,在第二个参数的方向上给出“下一个”不同的值;因此在这里,下一个不同的值接近于零。