我有一个内联函数执行频率到周期转换。计算精度必须使用 long 类型,而不是类型 double 。否则,可能会导致一些舍入错误。然后,该函数将结果转换回 double 。我想知道下面的代码,哪一行会保持计算类型长。无论参数栏是100,100.0还是33.3333。
double foo(long bar)
{
return 1000000/bar;
return 1000000.0/bar;
return (long)1000000/bar;
return (long)1000000.0/bar;
}
我自己尝试了,第4行有效。但在这种情况下只是想知道类型转换的概念。
修改
其中一个错误是1000000/37038 = 26,而不是26.9993。
答案 0 :(得分:2)
return 1000000/bar;
这将是一个很长的数学。
return 1000000.0/bar;
这会将数学作为双重数学。
return (long)1000000.0/bar;
这相当于第一个--1000000.0是一个双倍,但是你在分割之前将它强制转换,所以除法将在longs上完成。
答案 1 :(得分:1)
第一行(以及第三行更详细)将数学作为long
(在C ++中总是截断任何结果),然后将整数值作为double返回。我不明白您在bar
33.3333
long
的问题中所说的内容,因为这不是{{1}}值。
答案 2 :(得分:1)
正如你提出的那样,这个问题没有意义。
bar
是一个整数类型,因此1000000/bar
肯定会小于1000000
,这可以用double
1 ,所以没有办法在积分算术中执行全部计算可以提供更好的精度 - 实际上,你将得到整数除法,在这种情况下,对于{{1}的任何值, less 都是精确的因为它会截断小数部分。您在bar
到long
转化中遇到问题的唯一方法是double
转换为bar
,但如果超出double
的范围除法的最终结果将为0,因为它无论如何都是整数运算。
还是:
double
在1000000/bar
之间进行划分:1000000是long
或int
,具体取决于平台,long
是bar
;如果需要,第一个操作数将被提升为long
,然后执行整数除法。
long
在1000000.0/bar
之间进行划分:double
是一个1000000.0
字面值,因此double
会在划分前升级为bar
。
double
等同于第一个:强制转换优先于除法,强制(long)1000000/bar
(1000000
或long
)为{{1} }; int
是long
,执行bar
之间的划分。
long
等同于前一个:long
是(long)1000000.0/bar
,但您将其转换为1000000.0
,然后执行整数除法。
double
s(long
)和至少double
的尾数至少10个十进制数字作为超出范围之前可表示的十次幂(DBL_DIG
)(C99,附录E,¶4)。