我有一个像这样的功能:
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
解释为float
or double
,是否总是这样?还是取决于某些编译器标志?如果是a float
,那么1.0/3
也将是a float
,之后才转换为a double
。如果是这种情况,会导致精度损失,不是吗?
编辑2
我已经对此进行了测试g++
,事实证明,如果程序是用-fsingle-precision-constant
flag编译的,则确实会失去精度。
#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
它是安全的。
您显示的所有替代方法都不会降低精度(至少在编译器执行了标准要求的情况下才不会降低精度)。这就是所有二元运算符,其中一个操作数为a double
,另一侧自动提升为double
[并且通常,当两个操作数大小不同时,它们将提升为较大的一个]。
特别是,整数值[在尾数位数以下]总是精确地表示。
[显然,我们不知道calc
您的输入有什么作用-这可能是任何类型的错误的根源,但我想您实际上3.0/8.0
是0.375
在询问是否总是在您建议的情况下-当然3/8
会导致为零,因为两边都是整数]
根据原始问题进行编辑:
如果代码显示1.
或1.0
或0.3
或.3
,则为double
。如果你写的话0.5f
,那是一个float
。按照上述规则1.0/3
将是的结果double(1.0)/double(3.0)
。
从技术上讲,编译器可能仅支持一种浮点类型,并通过3种不同的编写方式-C和C ++标准不需要double
比拥有更多的位float
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句