什么是"int i = 1;为什么(i> = 60*60*1000/1*1000)"是真的吗?

Cel*_*ebi 36 c type-conversion

首先,定义两个没有括号的常量表达式是我的错:

#define BIG_INTERVAL 60 * 60 * 1000
#define SMALL_INTERVAL 1 * 1000

int i = 1;

if (i >= BIG_INTERVAL / SMALL_INTERVAL - 1)
{
    printf("Oops!\n");
}
Run Code Online (Sandbox Code Playgroud)

if宏展开后声明if(i >= 60 * 60 * 1000 / 1 * 1000 - 1).

那不是我的意图.但我发现一些奇怪的事情,如果我写的if (i >= 3600000000 - 1).这是假的.

什么类型60 * 60 * 1000 / 1 * 1000 - 1int

dan*_*n04 69

所有运营商都int返回int.是的,60 * 60 * 1000 / 1 * 1000 - 1是的int.但是3599999999的预期结果对于a来说太大了int,所以表达式实际上计算为-694967297(假设32位int和2的补码).

文字不会发生这种情况,3600000000因为整数文字大于可以保存完整值INT_MAX的类型.

  • "一种可以保持全部价值的类型" - 如果存在这种类型.对于超过"ULONG_MAX"的文字,不能保证. (21认同)
  • 整数(相对于堆栈)溢出:) (4认同)

Pet*_*nov 42

60*60*1000/1*1000 - 1 = 3600000*1000 - 1,溢出int类型,因此结果可以是任何东西(在你的情况下它是负数,但不一定是).

要实现你想要的东西put():

#define BIG_INTERVAL (60 * 60 * 1000)
#define SMALL_INTERVAL (1 * 1000)
Run Code Online (Sandbox Code Playgroud)

  • +1表示括号 - 这解释了真正的问题 - 尽管避免使用宏会提供更好的建议.仍然,"溢出int类型,所以它是负面的"使得这听起来像前者总是暗示后者.迂腐,但正式地说它是签名整数类型的未定义行为,并且在实践中它通常意味着你得到可能是正面或负面的垃圾......这里3,600,000*1,000恰好是<2 ^ 32但是> ^ ^ 31所以它是普通的负面具有32位`int`s的平台.... (15认同)

dpp*_*dpp 12

这是我的测试结果:

60 * 60 * 1000 / 1 * 1000 will result to -694967296

(60 * 60 * 1000) / (1*1000) will result to 3600
Run Code Online (Sandbox Code Playgroud)

您的操作存在问题,即计算的优先级.

您可能需要考虑查看C++运算符优先级http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx.你会找到结果变成-694967296的原因,我觉得溢出的效果.


Win*_*mer 9

如果使用int为64位的编译器,则会发现表达式的结果为false.如果使用int为32位或16位的编译器,则表达式具有未定义的行为,因为有符号整数的溢出不必包含.可能你的确只是环绕,但它并没有.

3600000000是在编译时可见的常量,因此如果int只有32位,那么编译器必须选择long long(或者只要long为64位).所以你的另一个表达式用足够的位来计算,以避免溢出,结果是正确的.