由于溢出,无法编译此代码:
byte number = 1000;
Console.WriteLine(number);
但是由于与溢出相同的原因,该值的值为1
byte number = 255;
number += 2;
Console.WriteLine(number);
我的问题是,为什么第一个示例给出错误而第二个示例不会给出错误?
答案 0 :(得分:1)
byte
type is 0 to 255
在第一个示例中,当您分配number = 1000
时,它超出了字节范围的限制,并给出了编译时错误。
在第二个示例中,您要分配number = 255
,因为255
在字节范围内。当您将2
添加到最大字节数限制即255
时,它从0
开始并打印1
作为结果
答案 1 :(得分:1)
第一个不会编译,因为无法将byte
设置为1000
。第二个之所以能够编译,是因为可以将byte
设置为255
,并且因为在执行超出其范围的算术运算时该值会溢出。
在第二个示例中,您都不会尝试将byte
设置为1000
。第二个示例中出现的每个操作都是有效的。但是第一个示例中的一个操作无效。
基本上,编译器不会尝试为您计算溢出。运行时将处理溢出。
答案 2 :(得分:0)
byte
是8位,并且可以关闭。用数学表示,它是0或1,分别是on和off。
因此,如果您连续放置8位,则可以开始用二进制表示数字:
00000000 = 0
00000001 = 1
00000010 = 2
...
11111111 = 255
正如其他人所指出的,当您将2加到255时,它溢出并回绕:
11111111 (255)
+00000010 (2)
---------------
00000001 (1)
您需要一个更大的原语(至少具有10位)来表示1000之类的数字,并且您的编译器知道这一点并试图警告您。
答案 3 :(得分:0)
差异归因于the rules surrounding C#'s checked
and unchecked
contexts。
恒定值(使用C#规范的良好定义的规则,编译器可以在编译时确定的常数)默认为checked
。尝试为数字类型分配超出范围的值(在您的情况下,将1000
分配给范围为byte
的{{1}})将导致编译时错误。您可以通过将表达式包装在[0,255]
上下文中来抑制这种情况。
unchecked
得出byte number = unchecked((byte) 1000);
Console.WriteLine(number);
。
非恒定值-即在运行时计算的值-默认为232
。这允许发生上溢/下溢。 This blog post explains the rationale for choosing unchecked
as the default.您可以选择制作一个表达式或块unchecked
,如果发生上溢/下溢,会导致运行时性能稍有下降,使运行时抛出异常。
checked
通过checked {
byte number = 255;
number += 2;
Console.WriteLine(number);
}
操作将System.OverflowException
抛出行。
或者,您可以将the -checked
compiler flag的默认位置设置为+=
,但标记为checked
的地方除外。