为什么这个不会溢出?

发布于 2024-07-26 17:38:18 字数 239 浏览 6 评论 0原文

给出这段代码:

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

Given this code:

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?");

And knowing an int can hold −32,768 to +32,767. Why doesn't this cause an overflow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

Hello爱情风 2024-08-02 17:38:18

在 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 上的未选中)。 它基本上归结为性能,因为检查溢出比忽略它要慢一点(这就是为什么默认行为通常是未检查,但我敢打赌,在某些编译器/配置中,你会得到第一个 z 赋值出现异常。)

In C#, the int type is mapped to the Int32 type, which is always 32-bits, signed.

Even if you use short, it still won't overflow because short + short returns an int by default. If you cast this int to short - (short)(x + y) - you'll get an overflowed value. You won't get an exception though. You can use checked behavior to get an exception:

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));
        }
    }
}

You can find information about checked (and unchecked) on MSDN. It basically boils down to performance, because checking for overflow is a little bit slower than ignoring it (and that's why the default behavior is usually unchecked, but I bet that in some compilers/configurations you'll get an exception on the first z assignment.)

彼岸花ソ最美的依靠 2024-08-02 17:38:18

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

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

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

Type: int
Range: -2,147,483,648 to 2,147,483,647

霓裳挽歌倾城醉 2024-08-02 17:38:18

虽然每个人都正确地说 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 可能仍然结果很好,具体取决于编译器如何处理晋升。

While everyone is correct in saying that an "int" type on a 32 bit machine is most likely 2^32, there is a glaring flaw in your methodology.

Let's assume that int was 16 bit. You're assigning a value that will overflow z, so z itself is overflowed. When you calculate x+y you're also overflowing the int type, it's very likely that both cases will overflow to the same value, meaning you'd hit your equality regardless(this is probably compiler dependent, I'm not quite sure whether x+y will be promoted).

The correct way to do your experiment would be for z to have a larger data type than x and y. For example(Sorry for plain C, I'm not much of C# person. Hopefully it illustrated the methodology, however.)

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");

Comparing sum and z is important as comparing x+y and z may still come out fine depending on how the compiler handles promotion.

骄傲 2024-08-02 17:38:18

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

In C#, an Int is 4 bytes. So it maxes out at 2^31 or 2,147,483,648. If you want a 2 byte integer, use a short instead of an int.

风向决定发型 2024-08-02 17:38:18

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

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

Because an int in .NET is a signed 32 bit number with a range of -2,147,483,648 to 2,147,483,647.

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

长不大的小祸害 2024-08-02 17:38:18

因为 int 是 32 位的,所以最多可容纳 ±2GB 的值。

Because ints are 32-bit, holding values up to ±2GB.

我很坚强 2024-08-02 17:38:18

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

An int's size is 4 byte so it can hold at least 2^31 which is around 2 billion.

迷爱 2024-08-02 17:38:18

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

The int keyword maps to the .NET Framework Int32 type, which can hold integers in the range from -2,147,483,648 to 2,147,483,647.

哭了丶谁疼 2024-08-02 17:38:18

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

in C# int (System.Int32) is of 32 bits which can happily store this value.

ゞ记忆︶ㄣ 2024-08-02 17:38:18

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

Int 表示 int32,其范围是 –2147483648 到 2147483647
您将获得 int16 的范围:–32768 到 32767

这就是它不会抛出任何错误的原因

you are given to print the result as "WTF?" .Then how should it display other value.

Int means int32 its range is –2147483648 to 2147483647
you are given the range of int16 :–32768 to 32767

This is the reason it is not throwing any error

硬不硬你别怂 2024-08-02 17:38:18

首先,您的代码在 int 范围内...但是,如果它不在范围内,那么它也不会抱怨...因为在 if 检查中执行 X+Y 后,您永远不会将值分配回任何变量...

假设如果你正在做 X * Y 那么它将被计算并且结果将是一个 long 值,然后变量 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; 

First of all your code is in the range for int... However if it were not in the range then it wont complain either... coz you are never assigning a value back to any variable after doing X+Y in your if check...

Suppose if you were doing X * Y then it'll be calculated and the result would be a long value then the value from variable Z is taken and promoted to a long then both would be compared... Remember the casting from a lower range primitive to upper range primitive value is implicit.

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; 
跨年 2024-08-02 17:38:18

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

All the above is true, however, it's important to know, that if you assign a number greater than 2^32, it will not compile!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文