类型为“long”的C ++计算

时间:2013-01-22 16:41:24

标签: c++ types precision

我有一个内联函数执行频率到周期转换。计算精度必须使用 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。

3 个答案:

答案 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 都是精确的因为它会截断小数部分。您在barlong转化中遇到问题的唯一方法是double转换为bar,但如果超出double的范围除法的最终结果将为0,因为它无论如何都是整数运算。

还是:

double

1000000/bar 之间进行划分:1000000是longint,具体取决于平台,longbar;如果需要,第一个操作数将被提升为long,然后执行整数除法。

long

1000000.0/bar 之间进行划分:double是一个1000000.0字面值,因此double会在划分前升级为bar

double

等同于第一个:强制转换优先于除法,强制(long)1000000/bar 1000000long)为{{1} }; intlong,执行bar之间的划分。

long

等同于前一个:long(long)1000000.0/bar ,但您将其转换为1000000.0,然后执行整数除法。


  1. C ++标准委托此事项的C标准,要求double s(long)和至少double的尾数至少10个十进制数字作为超出范围之前可表示的十次幂(DBL_DIG)(C99,附录E,¶4)。