7

当我尝试除以 1/60 或 1/(60*60) 时,它给出 0。即使在调试器窗口中也是如此。我有点困惑它可能是什么,因为 2/3 或 2.5/6 给出了结果。

我的代码:

int main()
{   
    double k1 = 1/60;
    cout << k1
        << endl;
    double k2 = 1/(60*60);
    cout << k2
        << endl;

    return 0;
}

我感谢您的帮助。

4

3 回答 3

11

由于您的两个操作数都是整数,因此编译器会执行整数除法(不计算小数部分)。如果至少一个操作数是浮点类型(如在您的其他示例中),则另一个被提升并执行浮点除法。

修复

制作至少一个浮点类型的操作数(doublefloat);你可以这样做,例如:

  • 使其成为double文字260是整数,60.0甚至60.double60.ffloat
  • 使用强制转换 ( double(60), (double)60)。

就我个人而言,我更喜欢直接使用double文字 - 并不是说​​强制转换对中等体面的编译器有任何性能损失,但就仅使用正确类型的文字而言,它感觉“错误”和冗长。(显然,当两个操作数都是变量而不是文字时,您必须使用强制转换)

常见的反对意见

  • “但我将它分配给一个double!”

    许多新手对这个事实感到困惑,因为他们认为将结果分配给 a应该是对编译double的某种暗示。事实上,它不是。

    对表达式进行的计算/提升完全独立于目的地的类型,这只是最后一步。子表达式的求值方式与结果的使用方式无关,因此所有类型提升/操作仅取决于操作数的类型。

  • 为什么要整数除法?

    即使参数都是整数(例如 VB6、IIRC),一些语言也会自动执行浮点除法,因为它对新手来说感觉更直观。这与 C/C++ 中的情况不同:当参数为整数时,除法是整数,因为在许多情况下您只是不关心小数,和/或出于性能原因最好不要使用 FPU(背景哲学在 C 和 C++ 中是“你不用为你不使用的东西付费”)。

    显然,可以使用单独的整数除法运算符来解决问题(VB 再次使用\),但恕我直言,我们在 C++ 中有足够的运算符。:)


  1. Nitpickers'corner:是的,这里实际上是一个初始化,而不是一个赋值,但我们谈论的是同一种误解。
  2. “文字”是源代码中包含的值。
于 2012-10-31T18:00:26.793 回答
2

分母也必须是十进制数。

double k1 = 1/60.0; //Should work

否则,您的程序基本上会截断所有小数。

LITTLE EXTRA:当你的分母是一个变量时,你必须转换它:

double k2 = 1/(double)myDenom;
于 2012-10-31T17:59:07.997 回答
2

该行double k1 = 1/60将由编译器评估为编译时常量。由于数字末尾没有“.0”,1/60因此将通过整数除法进行评估,因此为 0。

于 2012-10-31T18:00:00.027 回答