我希望舍入一个浮点值,将val
称为最接近的 0.05 的倍数。对我的意图的解释是here。我已经有val
的上限和下限,分别说valU
和valL
。我可以通过以下方式做到这一点:
[valL, valU]
范围内搜索 0.05 的最接近倍数,并相应地指定值。通过降低价值来解决关系。 OR 我发现方法-2有时会产生错误的结果。有人可以告诉我为什么方法-1是正确的方法吗?
答案 0 :(得分:1)
...围绕
float
值,将val
说成最接近0.05的倍数......
鉴于典型的binary floating point,最好的是
...将float
值舍入到最接近0.05 R
的倍数,并保存为最接近的可表示float
r
。
方法#1在角落情况下不清楚。 OP所拥有的不是代码,而是从数学角度而非实际C代码的代码概要。我会选择#2非常的变体#2。 @Barmar
几乎方法2:乘法,舍入,然后除法。
#include <math.h>
double factor = 20.0;
float val = foo();
double_or_float rounded_val = round(val * factor)/factor;
这种方法有两个微妙的点,使它更优越。
乘法的精确度和范围比引用的答案更高 - 这允许完全产品和非常精确商。如果仅使用float
数学计算乘积/商,则某些边缘情况最终会得到错误答案,当然一些大值会溢出到无穷大。
&#34;通过降低价值来解决问题。&#34;是一个艰难而不寻常的目标。听起来像是一个倾向于选择偏差的目标。无论当前的舍入方向如何,round(double)
都可以很好地将半径从零开始。要完成&#34;降低&#34;,请更改当前的舍入方向并使用rint()
或nearbyint()
。
#include <fenv.h>
int current_rounding_direction = fegetround();
fesetround(FE_DOWNWARD);
double rounded_val = rint(val * factor)/factor;
fesetround(current_rounding_direction);
... method-2有时会产生错误的结果......
OP需要发布代码和使用和计算的精确值,以便对各种方法的优缺点进行质量解释。试试printf("%a %a\n", val, rounded_val);
。通常,由于对代码使用printf("%f\n", val);
此外:&#34;我已经有val
的上限和下限,分别说valU
和valL
。我可以通过以下方式做到这一点:&#34;
这是非常准确的,因为valU
和valL
的偏差只是原始问题的迭代 - 找到rounded_val
。查找valL
和valU
的代码每个都需要一个上限和下限,否则什么是阻止范围[valL ... valU]
本身具有不准确的端点?