0

我有一个内联函数进行频率到周期的转换。计算精度必须使用long类型,而不是double类型。否则,可能会导致一些舍入错误。然后该函数将结果转换回double。我想知道在下面的代码中,哪一行会保持long类型的计算。无论参数栏是 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。

4

3 回答 3

2
return 1000000/bar;

这将做一个很长的数学。

return 1000000.0/bar;

这将作为双重计算。

return (long)1000000.0/bar;

这相当于第一个 -- 1000000.0 是一个双精度数,但是你在除法之前将它转换为 long,所以除法将在 long 上完成。

于 2013-01-22T16:45:17.540 回答
1

第一行(第三行更详细)将进行数学运算long(在 C++ 中总是截断任何结果),然后将整数值作为双精度值返回。我不明白你在关于bar存在的问题中所说的,33.3333因为那不是可能的long价值。

于 2013-01-22T16:46:17.713 回答
1

正如您提出的那样,这个问题没有意义。

bar是整数类型,所以1000000/bar肯定会小于1000000,可以用double1精确表示,所以用整数算术执行计算不可能提供更好的精度 - 实际上,你会得到整数除法,在这种情况对于 的任何值都不太bar精确,因为它会截断小数部分。在这里的转换中遇到问题的唯一方法是long转换为,但如果它超出除法的最终结果的范围,则为 0,就像在整数算术中一样。doublebardoubledouble

仍然:

1000000/bar

在 s之间进行除法long: 1000000 是 anint或 a long,取决于平台,bar是 a long;如果需要,第一个操作数被提升为 a long,然后执行整数除法。

1000000.0/bar

double在s:之间执行除法1000000.0double文字,因此在除法之前bar被提升double

(long)1000000/bar

相当于第一个:强制转换优先于除法,并且强制1000000(是 along或 an int)成为 a longbar是 a long,执行 s 之间的除法long

(long)1000000.0/bar

等效于前一个:1000000.0is a double,但您将其转换为 along然后执行整数除法。


  1. The C standard, to which the C++ standard delegates the matter, asks for a minimum of 10 decimal digits for the mantissa of doubles (DBL_DIG) and at least 10**37 as representable power of ten before going out of range (DBL_MAX_10_EXP) (C99, annex E, ¶4).
于 2013-01-22T16:46:29.793 回答