为什么这个不会溢出?
给出这段代码:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
在 C# 中,映射
int
类型到Int32
类型,其中始终是 32 位,有符号。即使您使用
short
,它仍然不会溢出,因为short
+short
返回int
。 如果将此int
转换为short
-(short)(x + y)
- 您将得到一个溢出值。 但你不会有例外。 您可以使用checked
行为来获取例外:您可以找到有关
已检查
的信息(以及 MSDN 上的未选中
)。 它基本上归结为性能,因为检查溢出比忽略它要慢一点(这就是为什么默认行为通常是未检查
,但我敢打赌,在某些编译器/配置中,你会得到第一个z
赋值出现异常。)In C#, the
int
type is mapped to theInt32
type, which is always 32-bits, signed.Even if you use
short
, it still won't overflow becauseshort
+short
returns anint
by default. If you cast thisint
toshort
-(short)(x + y)
- you'll get an overflowed value. You won't get an exception though. You can usechecked
behavior to get an exception:You can find information about
checked
(andunchecked
) 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 usuallyunchecked
, but I bet that in some compilers/configurations you'll get an exception on the firstz
assignment.)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
虽然每个人都正确地说 32 位机器上的“int”类型很可能是 2^32,但您的方法存在明显的缺陷。
假设 int 是 16 位。 您分配的值会溢出 z,因此 z 本身会溢出。 当您计算 x+y 时,您也会溢出 int 类型,这两种情况很可能会溢出到相同的值,这意味着您无论如何都会达到相等性(这可能取决于编译器,我不太确定是否x+y 将被提升)。
进行实验的正确方法是 z 具有比 x 和 y 更大的数据类型。 例如(对普通 C 感到抱歉,我不太懂 C#。不过,希望它说明了方法。)
比较 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.)
Comparing sum and z is important as comparing x+y and z may still come out fine depending on how the compiler handles promotion.
在 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.
因为.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
因为 int 是 32 位的,所以最多可容纳 ±2GB 的值。
Because ints are 32-bit, holding values up to ±2GB.
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.
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.
在C#中,int (System.Int32)是32位的,可以很好地存储这个值。
in C# int (System.Int32) is of 32 bits which can happily store this value.
你被要求将结果打印为“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
首先,您的代码在 int 范围内...但是,如果它不在范围内,那么它也不会抱怨...因为在 if 检查中执行 X+Y 后,您永远不会将值分配回任何变量...
假设如果你正在做 X * Y 那么它将被计算并且结果将是一个 long 值,然后变量 Z 的值被取出并提升为 long 然后两者将被比较...记住来自的转换较低范围原语到较高范围原语值是隐式的。
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.
上述所有内容都是正确的,但是,重要的是要知道,如果您分配一个大于 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!