失去精度?

埃里亚德

我有一个像这样的功能:

double calc( double x );

这些表达式中的任何一个都会使我失去准确性吗?

double y1 = calc( 1.0 / 3 );
double y2 = calc( 1.0 / 3.0 );

这些更准确吗?

double y3 = calc( static_cast<double>(1) / 3 )
double y4 = calc( static_cast<double>(1) / static_cast<double>(3) )

编辑

抱歉,我在这里输入了错误的数字。

但是,我的意思是将其1.0解释为floator double,是否总是这样?还是取决于某些编译器标志?如果是a float,那么1.0/3也将是a float,之后才转换为a double如果是这种情况,会导致精度损失,不是吗?

编辑2

我已经对此进行了测试g++,事实证明,如果程序是用-fsingle-precision-constantflag编译的,则确实会失去精度。

#include <iostream>
#include <limits>
#include <typeinfo>

long double calc( long double val)
{
  return val;
}
int main() {
  std::cout.precision(std::numeric_limits< long double >::max_digits10);

  std::cout << calc(1.0/3.0) << std::endl;
  std::cout << calc(static_cast<float>(1)/3) << std::endl;
  std::cout << calc(static_cast<double>(1)/3) << std::endl;
  std::cout << calc(static_cast<long double>(1)/3) << std::endl;
  std::cout << typeid(1.0).name() << std::endl;

  return 0;
}

结果是

0.333333343267440795898
0.333333343267440795898
0.33333333333333331483
0.333333333333333333342
f

因此,我决定使用static_cast< long double >(1) / 3它是安全的。

马特·彼得森(Mats Petersson)

您显示的所有替代方法都不会降低精度(至少在编译器执行了标准要求的情况下才不会降低精度)。这就是所有二元运算符,其中一个操作数为a double,另一侧自动提升为double[并且通常,当两个操作数大小不同时,它们将提升为较大的一个]。

特别是,整数值[在尾数位数以下]总是精确地表示。

[显然,我们不知道calc您的输入有什么作用-这可能是任何类型的错误的根源,但我想您实际上3.0/8.00.375询问是否总是在您建议的情况下-当然3/8会导致为零,因为两边都是整数]

根据原始问题进行编辑:

如果代码显示1.1.00.3.3,则为double如果你写的话0.5f,那是一个float按照上述规则1.0/3将是的结果double(1.0)/double(3.0)

从技术上讲,编译器可能仅支持一种浮点类型,并通过3种不同的编写方式-C和C ++标准不需要double比拥有更多的位float

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章