任务描述:总结归纳计算机编程中的各种数据类型,其表示形式和计算方法。重点关注类型转换、数值溢出和移位等操作。
一、整型
1、int型数据
int型数据在内存中占用4字节(32个二进制位),7位有效数字,数值的范围在 -2^31~ 2^31-1 。(signed)
unsigned int范围在0~2^32
- 表示方法
在所有被int类型占用的比特位中,左起第一个位(即最高位)就是符号位。int类型的符号位上,0表示正数,1表示负数。在32位操作系统下,其余后面31位是数值位。
-计算方法
补码计算
2、short型数据
short型数据占用的字节不多于int型的字节数,用2个字节(16个二进制位)表示。
3、long型数据
long型数据用4个字节(32个二进制位)表示(32位操作系统)
4、整型溢出
对于unsigned整型溢出,溢出后的数会以2^(8*sizeof(type))做模运算
即若一个unsigned char(8bit)溢出,会将溢出的值与256求模取余,例如:
signed char x=0xff;
printf("%d\n",++x); //输出0
/*因为 0xff+1 =256 ,256与256求模取余结果为0*/
对于signed整型的溢出,结果为实际计算结果
例如
signed char x=0x7f;
printf("%d\n",++x); //输出-128
/*因为 0x7f+1 =0x80即-128*/
5、 整型移位
无符号数的移位操作都是执行的逻辑移位 1
- 左移 << (逻辑左移)1
丢弃最高位,0补最低位
有符号数:当最左端符号移出去时,发生移位溢出,数值符号可能改变。
特殊情况:当左移位数超过该数值类型的最大位位数,编译器会用左移的位数去模类型的最大位数,然后取余
- 右移 >> (算数右移)2
有符号数:符号位向右移动后,正数补0,负数补1。
二、浮点型数据——带有小数或指数的数值数据
1、float型
float型数据在内存中占用4字节(32个二进制位),7位有效数字,数值的范围在-3.40E+38~3.40E+38
- 表示方法
将一个float型转化为内存存储格式的步骤为:
(1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部分的二进制方法。
(2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第一个有效数字的右边。
(3)从小数点右边第一位开始数出二十三位数字放入第22到第0位,系统默认去除了小数点前的1。
(4)如果实数是正的,则在第31位放入“0”,否则放入“1”。
(5)如果n 是左移得到,说明指数是正的,第30位放入“1”。
如果n是右移得到的或n=0,则第30位放入“0”。
(6)如果n是左移得到的,则将n减去1后化为二进制,并在左边加“0”补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在左边加“0”补足七位,再各位求反,再放入第29到第23位。
举例说明: 11.9的内存存储格式
(1) 将11.9化为二进制后大约是" 1011.
1110011001100110011001100…"。
(2) 将小数点左移三位到第一个有效位右侧: "1. 011 11100110011001100110 "。 保证有效位数24位,右侧多余的截取(误差在这里产生了 )。
(3)这已经有了二十四位有效数字,将最左边一位“1”去掉,得到“ 011 11100110011001100110
”共23bit。将它放入float存储结构的第22到第0位。
(4) 因为11.9是正数,因此在第31位实数符号位放入“0”。
(5)由于我们把小数点左移,因此在第30位指数符号位放入“1”。
(6)因为我们是把小数点左移3位,因此将3减去1得2,化为二进制,并补足7位得到0000010,放入第29到第23位。
最后表示11.9为: 0 1 0000010 011 11100110011001100110
-计算方法
计算12.0f-11.9f
12.0f 的内存存储格式为: 0 1 0000010 10000000000000000000000
11.9f 的内存存储格式为: 0 1 0000010 01111100110011001100110 可见两数的指数位完全相同,只要对有效数位进行减法即可。
12.0f-11.9f 结果: 0 1 0000010 00000011001100110011010
将结果还原为十进制为: 0.000 11001100110011010= 0.10000038
对于double型数据情况类似,只不过其阶码为11位,偏置量为1023,尾数为52位。
2、double型
double型数据在内存中占用8字节(64个二进制位),15位有效数字,数值的范围在-1.79E+308~-1.79E+308。
程序中,书写浮点数的一般格式
正负号 整数部分 . 小数部分 指数部分
- 整数部分和小数部分可任选,但不可以都没有
- 小数点和指数不能同时没有
- 指数部分是以一个字母e或E开头,后跟一个整数
3、浮点型溢出
浮点数上溢时,被赋予一个无穷大的值,printf函数显示的是inf。
浮点数下溢时,指数部分已经达到最小值,计算机只好将尾数部分进行右移,空出首位的二进制数,丢弃最后一位的二进制数。
以十进制为例,把一个4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.123E-10.虽然得到了结果,但是在计算过程中却损失了原本尾有效位上的数字。这种情况叫做***下溢(underflow)***。
C语言把损失了类型全精度的浮点值称为***低于正常的浮点值***。因此,把最小的正浮点数除以2将得到一个低于正常的值。如果除以一个非常大的值,会导致所有位都为0。
4、移位操作
C语言不支持浮点数的移位操作
三、字符型数据
1、char型
char型数据在内存中占用1字节(8个二进制位)
字符型数据内部表示是字符的ASCII码
字符的ASCII码也可看作-128~127或0~255的一个整数
-表示形式
在C语言中,实际上字符型数据在内存中是以二进制形式存放的。
-计算方法
在对字符型数据进行相加减运算的时候,系统会首先会将char型数据以隐形的方式转化成int型数据再进行相加减运算的。
四、类型转换
1、自动类型转换
在不同类型的混合运算中,编译器也会自动地转换数据类型,将参与运算的所有数据先转换为同一种类型,然后再进行计算。转换的规则如下:
- 转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。
- 所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。
- char 和 short 参与运算时,必须先转换成 int 类型。
2、强制类型转换
强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换。换句话说,自动类型转换不需要程序员干预,强制类型转换必须有程序员干预。