Fist:why?
有时候只知道什么还不够,我们还需要为什么,所以我在整个数据结构系列中都要追寻这个答案。
Q1:为什么需要整型数据。
因为整型数据结构跟生活密切相关,生活中、数学中到处都是整型数字。
所以我们需要计算机也能表示整型数据。
整型数据结构(Integer)
整型数据在计算机低层组织结构包括无符号数、有符号数
1.1 无符号数
现在常见的编程语言中支持无符号数的只有C\C++,
通过unsigned关键字来指定无符号数。
就像我们使用十进制数字一样的,无符号二进制数字也是用加权和方法。
例:
10机制:4982
数字的位4321 (‘2’位于第一位,8位于第二位,‘9’位于第三位,‘4位于’第四位)
所以它表示的值为= 2 X 10^(1-1) + 8 X 10^(2-1) + 9 X 10^(3-1) + 4 X 10^(4-1) [’^'符合表示幂]
所以无符号整数表示值也是这样:
---- -1000 0000
—位8765 4321
表示的值为=1 X 2^(8-1)+ 0 X 2^(7-1)…
c语言中int型占4个字节32位表示的值为0至2^(32-1)-1 总共2^32个数。
int型变量的范围是 -2147483648~2147483647
unsigned int型变量的范围是0~4294967295
1.2 有符号数
顾名思义,有符号数就是拥有标明正负的整数,我们在平常的使用过程中是最常见的,但是计算机在实现的时候却有三种数据结构。
分别是原码、反码、补码。
1.2.1 原码
原码就是用首位留一位作为符号位。
但是只是多一个符号位会出现正零、负零这样奇怪的数字。
例如:如果我们用首位0表示正的话,8位二进制数字能表示
0000 0000 - 0111 1111 是+0到127
1000 0000 - 1111 1111 是-0到-127
是不是很怪异
1.2.2 反码
正数:表示与原码一样
负数:
反码的组织策略是,除首位符号位外,按位去反。
比如说:-64的原码为 1100 0000 反码为1011 1111
如计算负值的时候为首位的负值 -(1 X 2^(8-1)-1),加上剩余位所有的值.
1011 1111
-64 = -(1 X 2^(8-1)-1) + 0 X 2^(6-1) + 1X 2^(5-1) + 1X 2^(4-1)
+1X 2^(3-1)+ 1X 2^(2-1) + 1X 2^(1-1)
-64=-127 + 32 +16 +8 + 4 + 2 + 1
但是这样还是会出现原码中的正零、负零
1.2.3 补码
补码是计算机中最常见的有符号数表达方式。
正数与原码一样:
为了解决反码正负零问题,补码为反码去掉符号位末尾减1.
-64的反码为1011 1111 补码为1011 1110
其中1111 1111 表示-128
但是在实际的运算过程中会有这三种表达方式的互相转换。
1.2.4 原码、反码、补码的互相转换
正数都一样
正数都一样
正数都一样
负数:
1.原码转反码:符号位不变,数值位按位取反
2.原码转补码:符号位不变,数值位按位取反,末尾再加1
3.反码转原码:符号位不变,按位取反。
4.反码转补码:末尾加1
补码能表示值比原码、反码多一个所以转换过程会出现异常,-128会丢失
5.补码转原码:末尾减1、符号位不变,按位取反
6.补码转反码:末尾减1
1.2.5作用
那么分这么多种类是为啥呢?
原码:可直观反映出数据的大小。
反码:解决负数加法运算问题,将减法运算转换为加法运算,从而简化运算规则。
补码:解决负数加法运算正负零问题,弥补了反码的不足。