为什么不溢出?

时间:2009-07-14 05:38:46

标签: c# .net visual-studio int integer-overflow

鉴于此代码:

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可以容纳-32,768到+32,767。为什么这不会导致溢出?

12 个答案:

答案 0 :(得分:21)

在C#中,int类型映射到Int32类型,该类型始终为32位,已签名。

即使您使用short,它仍然不会溢出,因为short + short默认返回int。如果您将此int投射到short - (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));
        }
    }
}

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

答案 1 :(得分:10)

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

输入:int 范围:-2,147,483,648至2,147,483,647

答案 2 :(得分:6)

虽然大家都说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可能仍然很好,这取决于编译器如何处理促销。

答案 3 :(得分:2)

在C#中,Int是4个字节。所以最大值为2 ^ 31或2,147,483,648。如果你想要一个2字节的整数,请使用short而不是int。

答案 4 :(得分:2)

因为.NET中的int是签名的32位数字,其范围 -2,147,483,648到2,147,483,647

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

答案 5 :(得分:1)

因为整数是32位,保持值最高为±2GB。

答案 6 :(得分:1)

int的大小为4字节,因此它至少可以容纳2 ^ 31,大约是20亿。

答案 7 :(得分:1)

int关键字映射到.NET Framework Int32 type,它可以保存-2,147,483,648到2,147,483,647范围内的整数。

答案 8 :(得分:1)

C# int(System.Int32)中的

是32位,可以很好地存储该值。

答案 9 :(得分:1)

你被给予打印结果为“WTF?”那怎么显示其他价值呢。

Int表示int32,其范围是-2147483648到2147483647 你得到的范围是int16:-32768到32767

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

答案 10 :(得分:1)

首先你的代码在int的范围内...但是如果它不在范围内那么它也不会抱怨...因为你在执行X + Y之后永远不会将值赋给任何变量如果你检查......

假如你正在做X * Y然后它将被计算并且结果将是一个长值,那么从变量Z获取值并将其提升为long然后两者将被比较...记住来自较低范围的原语到较高范围的原语值是隐含的。

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; 

答案 11 :(得分:0)

以上所有都是正确的,但重要的是要知道,如果你指定一个大于2 ^ 32的数字,它将无法编译!