【发布时间】:2015-11-12 18:44:35
【问题描述】:
我想用 C++ 计算以下形式的总和
float result = float(x1)/y1+float(x2)/y2+....+float(xn)/yn
xi,yi 都是整数。结果将是实际值的近似值。该近似值小于或等于实际值至关重要。我可以假设我所有的价值观都是有限的和积极的。 我尝试在此代码 sn-p 中使用 nextf(,0)。
cout.precision( 15 );
float a = 1.0f / 3.0f * 10; //3 1/3
float b = 2.0f / 3.0f * 10; //6 2/3
float af = nextafterf( a , 0 );
float bf = nextafterf( b , 0 );
cout << a << endl;
cout << b << endl;
cout << af << endl;
cout << bf << endl;
float sumf = 0.0f;
for ( int i = 1; i <= 3; i++ )
{
sumf = sumf + bf;
}
sumf = sumf + af;
cout << sumf << endl;
可以看到正确的解决方案是3*6,666... +3.333.. = 23,3333...
但作为输出我得到:
3.33333349227905
6.66666698455811
3.33333325386047
6.66666650772095
23.3333339691162
即使我的总和小于它们应表示的值,但它们的总和却不是。在这种情况下,将nextafterf 应用到sumf 会得到更小的23.3333320617676。但这总是有效吗?舍入误差是否可能变得如此之大以至于nextafterf 仍然让我高于正确值?
我知道我可以通过实现分数类并精确计算所有内容来避免这种情况。但我很好奇是否有可能用花车实现我的目标。
【问题讨论】:
-
IEEE754/floats 会出现舍入和表示错误。如果您绝对需要精确值,请考虑使用分数或任意精度的数字类型。
-
将舍入模式设置为
FE_DOWNWARD,然后进行计算。或者nextafterf(foo, -1.0/0.0)你的计算2n-1次。 -
@RegretBomb:好像你连问题都懒得看……
-
@tmyklebu 略显多余的文字并不意味着我没有阅读您的问题。
-
@RegretBomb 就好像你读的太少了,你甚至没有看到提问者和告诉你你的言论无关紧要的人是不同的人。
标签: c++ floating-point rounding precision floating-point-precision