什么是将双精度值舍入到(稍微)更低精度的好方法?

Mul*_*deR 7 c++ rounding floating-point-precision

我的问题是我必须使用一个thrid-party函数/算法,它将一个double -precision值数组作为输入,但显然可能对输入数据中的非常小的变化敏感.但是对于我的应用程序,我必须获得相同的结果(几乎)相同的输入!特别是我有两个测试输入数组,它们在小数点后的第5个位置是相同的,但我仍然得到不同的结果.那么导致"问题"的原因必须是小数点后的第5个位置之后.

现在我的想法是将输入四舍五入到稍低的精度,以便从非常相似的输入获得相同的结果,但不是 100%相同.因此,我正在寻找一种好的/有效的方法来将精度值舍入到稍低的精度.到目前为止,我使用此代码舍入到小数点后的第9个位置:

double x = original_input();
x = double(qRound(x * 1000000000.0)) / 1000000000.0;
Run Code Online (Sandbox Code Playgroud)

这里qRound()是Qt的正常的double到整数舍入函数.这段代码有效,它确实通过两个"有问题"的测试集解决了我的问题.但是:有更有效的方法吗?

还有什么困扰我:对于-100.0到100.0范围内的输入数据,舍入到小数点后的第9个位置可能是合理的(就像我当前的输入数据一样).但是,例如,对于-0.001到0.001范围内的输入数据,可能太多(即,太多精度损失).不幸的是,我不知道在其他情况下我的输入值会在什么范围内......

毕竟,我认为我需要的是一个函数,它执行以下操作:通过适当的舍入,将给定的精度值X切换到小数点后的最多LN位置,其中L是位置数在double -precision可以存储(表示)给定值的小数点之后; 和N是固定的,就像3.这意味着对于"小"值,我们将允许小数点后的位置比"大"值更多.换句话说,我想将64位浮点值舍入到(稍微)更小的精度,如60位或56位,然后将其存储回64位双精度值.

你能理解这个吗?如果是这样,你能否建议一种在C++中有效地做到这一点的方法???

提前致谢!

Xav*_*olt 1

如果您看一下双位布局,您可以看到如何将其与一些按位魔术结合起来以实现快速(二进制)舍入到任意精度。您有以下位布局:

SEEEEEEEEEEEFFFFFFFFFFF.......FFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)

其中S是符号位,Es 是指数位,Fs 是小数位。您可以像这样制作位掩码:

11111111111111111111111.......1111000000
Run Code Online (Sandbox Code Playgroud)

并按位与 ( &) 将两者相加。结果是原始输入的舍入版本:

SEEEEEEEEEEEFFFFFFFFFFF.......FFFF000000
Run Code Online (Sandbox Code Playgroud)

您可以通过更改尾随零的数量来控制截断的数据量。更多的零=更多的舍入;更少=更少。您还可以获得所需的其他效果:小输入值受到的影响按比例小于大输入值,因为每个位对应的“位置”是由指数确定的。

希望有帮助!

警告: 这在技术上是截断而不是真正的舍入(所有值都将变得更接近于零,无论它们与其他可能的结果有多接近),但希望它对您的情况同样有用。