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++中有效地做到这一点的方法???
提前致谢!
如果您看一下双位布局,您可以看到如何将其与一些按位魔术结合起来以实现快速(二进制)舍入到任意精度。您有以下位布局:
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)
您可以通过更改尾随零的数量来控制截断的数据量。更多的零=更多的舍入;更少=更少。您还可以获得所需的其他效果:小输入值受到的影响按比例小于大输入值,因为每个位对应的“位置”是由指数确定的。
希望有帮助!
警告: 这在技术上是截断而不是真正的舍入(所有值都将变得更接近于零,无论它们与其他可能的结果有多接近),但希望它对您的情况同样有用。