我有个疑问
当两个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
编译器的大小,因为所有值都会自动提升到计算中int
或unsigned int
计算中.您提到了具有16位累加器的硬件,并且C编译器通常(但不总是)使用本机寄存器大小作为大小int
,这就是我假设int
为16位的原因.
是的,会有溢出.子表达式a + b的类型为short,并且只有在它被评估之后才会将结果转换为long.做这个:
c = (unsigned long)a + b;
Run Code Online (Sandbox Code Playgroud)
这将导致a 在加法发生之前被投射很长时间,这反过来将导致b也被投射到很长时间.因此,发生了两个长的添加,并且不会发生溢出.