18

What actually happens when a Byte overflows?

Say we have

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

If we now do this addition

byte byte3 = byte1 + byte2;

I think we'll end up with byte3 = 94 but what actually happens? Did I overwrite some other memory somehow or is this totally harmless?

4

12 回答 12

14

It's quite simple. It just does the addition and comes off at a number with more than 8 bits. The ninth bit (being one) just 'falls off' and you are left with the remaining 8 bits which form the number 94.

(yes it's harmless)

于 2010-11-11T16:58:40.230 回答
8

The top bits will be truncated. It is not harmful to any other memory, it is only harmful in terms of unintended results.

于 2010-11-11T16:59:07.233 回答
6

In C# if you have

 checked { byte byte3 = byte1 + byte2; }

It will throw an overflow exception. Code is compiled unchecked by default. As the other answers are saying, the value will 'wrap around'. ie, byte3 = (byte1 + byte2) & 0xFF;

于 2010-11-11T17:00:52.553 回答
5

The carry flag gets set... but besides the result not being what you expect, there should be no ill effects.

于 2010-11-11T16:59:05.993 回答
5

Typically (and the exact behaviour will depend on the language and platform), the result will be taken modulo-256. i.e. 150+199 = 349. 349 mod 256 = 93.

This shouldn't affect any other storage.

于 2010-11-11T17:00:03.913 回答
5

Since you have tagged your question C#, C++ and C, I'll answer about C and C++. In c++ overflow on signed types, including sbyte (which, I believe, is signed char in C/C++) results in undefined behavior. However for unsigned types, such as byte (which is unsigned char in C++) the result is takes modulo 2n where n is the number of bits in the unsigned type. In C# the second rule holds, and the signed types generate an exception if they are in checked block. I may be wrong in the C# part.

于 2010-11-11T17:00:36.520 回答
4

Overflow is harmless in c# - you won't overflow memory - you simply obly get the last 8 bits of the result. If you want this to this an exception, use the 'checked' keyword. Note also that you may find byte+byte gives int, so you may need to cast back to byte.

于 2010-11-11T17:01:16.487 回答
3

The behavior depends on the language.

In C and C++, signed overflow is undefined and unsigned overflow has the behavior you mentioned (although there is no byte type).

In C#, you can use the checked keyword to explicitly say you want to receive an exception if there is overflow and the unchecked keyword to explicitly say you want to ignore it.

于 2010-11-11T17:00:05.987 回答
2

Leading bit just dropped off.

于 2010-11-11T16:59:06.927 回答
2

And arithmetic overflow occurs. Since 150+199=349, binary 1 0101 1101, the upper 1 bit is dropped and the byte becomes 0101 1101; i.e. the number of bits a byte can hold overflowed.

No damage was done - e.g. the memory didn't overflow to another location.

于 2010-11-11T17:00:36.800 回答
1

就 C# 而言,将两个 type 值byte相加会产生一个 type 值,int然后必须将其强制转换回byte.

因此,您的代码示例将导致编译器错误,而无需转换回字节,如下所示。

byte byte1 = 150; // 10010110  
byte byte2 = 199; // 11000111

byte byte3 = (byte)(byte1 + byte2);

有关这方面的更多详细信息,请参阅 MSDN。另请参阅C# 语言规范,第 7.3.6 节数字提升。

于 2011-10-12T20:04:11.763 回答
1

让我们看看实际发生了什么(在 C 中(假设您有适当的数据类型,正如一些人指出的那样,C 没有“字节”数据类型;尽管如此,可以添加 8 位数据类型)) . 如果这些字节在栈上声明,它们就存在于主存中;在某些时候,字节将被复制到处理器进行操作(我跳过了几个重要的步骤,例如处理器或缓存......)。一旦进入处理器,它们将被存储在寄存器中;处理器将对这两个寄存器执行加法操作以将数据加在一起。 这就是混乱的原因发生的地方。 CPU 将以本机(或有时,指定)数据类型执行加法操作。假设 CPU 的本机类型是 32 位字(并且该数据类型用于加法操作);这意味着这些字节将存储在 32 位字中,高 24 位未设置;add 操作确实会在目标 32 位字中溢出。但是(这是重要的一点)当数据从寄存器复制回堆栈时,只有最低 8 位(字节)将被复制回堆栈上目标变量的位置。(请注意,这里的字节打包和堆栈也涉及一些复杂性。)

所以,这就是结果;add 导致溢出(取决于选择的特定处理器指令);然而,数据被从处理器复制到适当大小的数据类型中,因此溢出是看不见的(并且是无害的,假设编译器编写正确)。

于 2010-11-11T17:14:42.987 回答