有符号数与无符号数的四则运算

来源:互联网 发布:java对特殊字符转义 编辑:程序博客网 时间:2024/05/21 09:47

有符号数与无符号数作四则运算

基本原则:
1、一般singed 型数据和unsigned型数据进行四则运算,是要转换成unsigned的,
2、两种数据类型相乘,会将其转换成范围更广的数据类型,再作运算。如unsigned short 与int相乘,会被转成int再作相乘,其最终结果也被认为是有符号的

例:
1) 
unsigned short a;
int b;
a*b 将会被认为是一个有符号型 ( int 型的表示范围比unsigned short型表示范围更宽 )
2)
unsigned int a;
int b;
a*b 将会被认为是一个无符号型 ( unsigned int型的表示范围比 int型表示范围更宽 )
3)
操作数混合了有符号数,无符号数
int a = -1;
unsigned int b = 2;
b/a;

对于该情形,因为涉及到不同符号数的混合计算,在计算之前需要先对操作数进行规整化的动
作,规整的原则就是如果操作数中存在至少一个无符号数(前提要求两个操作数据位长是一致的,该例中都是32位),
则所有操作数都被转化为无符号数,
运算操作也采用相应的无符号操作符进行,计算完的结果也是一个无符号数。

举例来说:

(unsigned int)b / (signed int)a
 会采用无符号除法进行,其实质相当于
(unsigned int)b / (unsigned int)a
计算结果也是一个无符号数,结果为(unsigned int)2 / (unsigned int)-1 = 0x2/0xFFFFFFFF = 0
再进一步,对于运算-2 / -1,如果采用有符号数运算,结果是2,采用无符号数运算,结果则是0



举例
在工作中遇到一个问题,
unsigned short a1 =  1920;
unsigned short a2 = 3840;
a1*2^20 计算得出为一个正数 ( a1为unsigned short型,2^20为int型,计算时会先转换成int型再作运算,最终结果将是int型 )
    1920 * 2^20 = 0x78000000    ( int 型0x78000000实际也是一个正数 )
a2*2^20 计算得出为一个负数
    3840 * 2^20 = 0xF0000000 = -268435456  ( int型0xF0000000实际是一个负数 )

分析如下
2^20 * 1920 = 0x78000000
2^20 * 3840 = 0xF0000000 
在计算机中,将0xF000000当作一个负数作处理,其数值为-268435356 ( 具体转化过程参考另一文档《负数在计算机中如何表示?》 )

如下所示code的结果为 
-268435456
fffdddde 167d30
-139810 1473840


<span style="font-size:14px;">#include <stdio.h>main(){unsigned short InW1 = 3840;unsigned short OutW1 = 1920;unsigned short InW2 = 1920;unsigned short OutW2 = 1366;unsigned int Factor1;unsigned int Factor2;int parameter = (1<<20);Factor1 = (InW1*parameter)/OutW1;Factor2 = (InW2*parameter)/OutW2;printf("%d\n",(InW1*parameter));printf("%x %x \n",Factor1, Factor2);printf("%d %d \n",Factor1, Factor2);}</span>




我们在面试时经常给你一个非常简单的式子,比如unsigned  int a,int b;请你分析a+b,a*b啥现象,不要轻心,这个东西返回的东西很奇怪的,或者问你(a+b) > 0是真是假,这样我们就回到了开始提出的问题,由于是一个负数乘了一个DWORD,所以返回的是一个无符号的(BC编译器,可能他这儿是无符号的,看具体的编译器),我们加一个有符号的强制转换后,发现正常,说明正好我们提出的猜想是完全正确的。



分类: C语言

0 0
原创粉丝点击