溢出c

2 c overflow integer-overflow

我有个疑问

当两个16位值加上最大值时,16位机器会出现溢出吗?

我会详细说明

unsigned short a;
unsigned short b;
unsigned long  c;

c=(unsigned long)(a+b);
Run Code Online (Sandbox Code Playgroud)

谈到16位处理器,累加器将是16位大小.上述声明是否会溢出?请澄清.

Edd*_*die 13

使用这些定义并假设unsigned short== 16位和int== 16位和unsigned long== 32位(注意大小int很重要):

unsigned short a, b;
unsigned long  c;
Run Code Online (Sandbox Code Playgroud)

这两个陈述会做不同的事情:

c = (unsigned long)(a + b);
c = (unsigned long)a + b;
Run Code Online (Sandbox Code Playgroud)

第一个 - 你展示的那个 - 将首先将数字添加为unsigned short,丢弃任何溢出 - 然后扩展为unsigned long.这可能就是你问的原因.第二个将a转换为unsigned long,然后添加两个数字,b在添加之前扩展为unsigned long.

你也可以这样做:

c = (unsigned long)a + (unsigned long)b;
Run Code Online (Sandbox Code Playgroud)

但这是不必要的,因为在计算中存在一个unsigned long将导致另一个从短到长自动提升.

从而:

a = 0x8001;
b = 0x8001;
c = (unsigned long)(a + b);   /* c is assigned 0x00000002 */
c = (unsigned long)a + b;     /* c is assigned 0x00010002 */
Run Code Online (Sandbox Code Playgroud)

所有这些都取决于您的特定编译器及其变量的大小.具体取决于int编译器的大小,因为所有值都会自动提升到计算中intunsigned int计算中.您提到了具有16位累加器的硬件,并且C编译器通常(但不总是)使用本机寄存器大小作为大小int,这就是我假设int为16位的原因.


Ste*_*202 9

是的,会有溢出.子表达式a + b的类型为short,并且只有在它被评估之后才会将结果转换为long.做这个:

c = (unsigned long)a + b;
Run Code Online (Sandbox Code Playgroud)

这将导致a 在加法发生之前被投射很长时间,这反过来将导致b也被投射到很长时间.因此,发生了两个长的添加,并且不会发生溢出.

  • 是否存在溢出取决于所讨论的编译器中int的大小.如果int与unsigned的大小相同,那么你是正确的.如果int大于unsigned,则在计算完成之前,变量将自动提升为unsigned int. (2认同)