2

鉴于此代码:

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。为什么这不会导致溢出?

4

12 回答 12

21

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

即使您使用short,它仍然不会溢出,因为short+默认short返回 an 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

于 2009-07-14T05:59:55.700 回答
10

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

类型:int 范围:-2,147,483,648 到 2,147,483,647

于 2009-07-14T05:41:14.897 回答
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 可能仍然很好,这取决于编译器如何处理提升。

于 2009-07-14T05:54:25.960 回答
2

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

于 2009-07-14T05:41:36.097 回答
2

因为 .NET 中的 int 是带符号的 32 位数字,范围为-2,147,483,648 到 2,147,483,647

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

于 2009-07-14T05:42:46.187 回答
1

因为 int 是 32 位的,所以可以保存高达 ±2GB 的值。

于 2009-07-14T05:41:16.393 回答
1

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

于 2009-07-14T05:41:44.393 回答
1

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

于 2009-07-14T05:42:00.230 回答
1

在 C# 中int (System.Int32)是 32 位的,可以愉快地存储这个值。

于 2009-07-14T05:42:29.277 回答
1

您被要求将结果打印为“WTF?” .那么它应该如何显示其他值。

Int 表示 int32 它的范围是 –2147483648 到 2147483647 给定 int16 的范围:–32768 到 32767

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

于 2009-07-14T05:48:35.613 回答
1

首先,您的代码在 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; 
于 2009-07-14T05:55:42.197 回答
0

以上所有内容都是正确的,但是,重要的是要知道,如果您分配的数字大于 2^32,它将无法编译!

于 2009-07-14T07:44:26.503 回答