代码之家  ›  专栏  ›  技术社区  ›  Kredns

为什么不溢出?

  •  2
  • Kredns  · 技术社区  · 17 年前

    给定此代码:

    int x = 20000;
    int y = 20000;
    int z = 40000;
    
    // Why is it printing WTF? Isn't 40,000 > 32,767?
    if ((x + y) == z) Console.WriteLine("WTF?");
    

    知道一个int可以持有32768到+32767。为什么这不会导致溢出?

    12 回复  |  直到 12 年前
        1
  •  21
  •   Blixt    17 年前

    在C语言中, int 类型映射到 Int32 类型,始终为32位,有符号。

    即使你使用 short ,它仍然不会溢出,因为 短的 + 短的 返回一个 int 默认情况下。如果你投这个 int 短的 - (short)(x + y) -您将得到一个溢出值。不过你不会有例外的。你可以使用 checked 获取异常的行为:

    using System;
    
    namespace TestOverflow
    {
        class Program
        {
            static void Main(string[] args)
            {
                short x = 20000;
                short y = 20000;
                short z;
    
                Console.WriteLine("Overflowing with default behavior...");
                z = (short)(x + y);
                Console.WriteLine("Okay! Value is {0}. Press any key to overflow " +
                    "with 'checked' keyword.", z);
                Console.ReadKey(true);
    
                z = checked((short)(x + y));
            }
        }
    }
    

    您可以找到有关 选中的 (和) unchecked 在MSDN上。它基本上归结为性能,因为检查溢出比忽略它慢一点(这就是为什么默认行为通常是 未检查的 但我敢打赌,在某些编译器/配置中,第一个会出现异常 z 指派。)

        2
  •  10
  •   Scoregraphic    17 年前

    http://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx

    类型:int 范围:-2147483648至2147483647

        3
  •  6
  •   Falaina    17 年前

    虽然每个人都说32位机器上的“int”类型最有可能是2^32,但您的方法论中有一个明显的缺陷。

    假设int是16位。您分配的值将溢出z,所以z本身就是溢出的。当计算x+y时,也会溢出int类型,很可能两种情况都会溢出到相同的值,这意味着您将达到相等(这可能与编译器有关,我不确定x+y是否会被提升)。

    做实验的正确方法是Z的数据类型要大于X和Y。例如(对于普通的C对不起,我不太喜欢C人)。希望它能说明方法论。)

    int x = INT_MAX;
    int y = INT_MAX;
    int sum = x + y;
    long long z = INT_MAX+INT_MAX;
    if(sum == z) 
     printf("Why didn't sum overflow?!\n");
    

    比较sum和z很重要,因为比较x+y和z可能仍然很好,这取决于编译器如何处理升级。

        4
  •  2
  •   Jeff Siver    17 年前

    在c中,int是4个字节。所以它的最大值是2^31或2147483648。如果需要2字节的整数,请使用short而不是int。

        5
  •  2
  •   Maltrap    17 年前

    因为.NET中的int是 符号32位 范围为的数字 -2147483648至2147483647 .

    参考文献: http://msdn.microsoft.com/en-us/library/5kzh1b5w(VS.80).aspx

        6
  •  1
  •   Vinay Sajip    17 年前

    因为ints是32位的,所以将值保持在_?2GB以内。

        7
  •  1
  •   Gábor Hargitai    17 年前

    一个int的大小是4字节,所以它可以容纳至少2^31,大约20亿。

        8
  •  1
  •   Christian C. Salvadó    17 年前

    这个 int 关键字映射到.NET框架 Int32 type ,它可以保存-2147483648到2147483647范围内的整数。

        9
  •  1
  •   this. __curious_geek    17 年前

    在C中 int(系统.int32) 是32位的,可以愉快地存储这个值。

        10
  •  1
  •   anishMarokey FIre Panda    17 年前

    您可以将结果打印为“wtf”?,那么它应该如何显示其他值。

    Int表示Int32,其范围为2147483648至2147483647。 您的范围为Int16:_“32768到32767

    这就是它没有抛出任何错误的原因

        11
  •  1
  •   S M Kamran    17 年前

    首先,您的代码在int的范围内…但是如果它不在范围内,它也不会抱怨…因为在if检查中执行x+y之后,永远不会将值赋回任何变量…

    假设您正在做x*y,那么它将被计算出来,结果将是一个长值,然后取变量z的值并将其提升为一个长值,然后将两者进行比较…记住,从较低范围原语到较高范围原语值的转换是隐式的。

    int x = 200000; //In your code it was 20000
    int y = 200000; //In your code it was 20000
    int z = 40000;
    
    // Why is it printing WTF? Isn't 40,000 > 32,767?
    // Note: X + Y = 200000 and not < 32,767 
    // would pass compiler coz you are not assigning and values are compared as longs
    // And since it's not equals to 40,000 the WTF did not got printed
    if ((x + y) == z) Console.WriteLine("WTF?");     
    // And x * y >= z is true WTF MULTIPLY got printed
    if ((x * y) >= z) Console.WriteLine("WTF MULTIPLY?"); 
    // Compiler would fail since x can't hold 40,00,00,00,000
    x = x * y; 
    
        12
  •  0
  •   BenMorel Manish Pradhan    12 年前

    以上都是正确的,但是,重要的是要知道,如果指定的数字大于2^32,它将不会编译!

    推荐文章