阅读:        作者:并排逗比北边跑

《深入理解计算机系统》2.2整数表示

整数数据类型

C语言中不同字长的机器和编译器会分配不同字节大小.
long类型是唯一与机器相关的.

32位机器上C语言的整数数据类型的典型取值范围
负数的取值范围比正数大1

C data type Minimum Maximum
char −128 127
unsigned char 0 255
short [ int ] −32,768 32,767
unsigned short [ int ] 0 65,535
int −2,147,483,648 2,147,483,647
unsigned [ int ] 0 4,294,967,295
long [ int ] −2,147,483,648 2,147,483,647
unsigned long [ int ] 0 4,294,967,295
long long [ int ] −9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned long long [ int ] 0 18,446,744,073,709,551,615

64位机器上C语言的整数数据类型的典型取值范围
负数的取值范围比正数大1

C data type Minimum Maximum
char −128 127
unsigned char 0 255
short [ int ] −32,768 32,767
unsigned short [ int ] 0 65,535
int −2,147,483,648 2,147,483,647
unsigned [ int ] 0 4,294,967,295
long [ int ] −9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned long [ int ] 0 18,446,744,073,709,551,615
long long [ int ] −9,223,372,036,854,775,808 9,223,372,036,854,775,807
unsigned long long [ int ] 0 18,446,744,073,709,551,615

C语言的整数数据类型的保证的取值范围
取值范围是对称的

C data type Minimum Maximum
char −128 127
unsigned char 0 255
short [ int ] −32,767 32,767
unsigned short [ int ] 0 65,535
int −32,767 32,767
unsigned [ int ] 0 65,535
long [ int ] −2,147,483,647 2,147,483,647
unsigned long [ int ] 0 4,294,967,295
long long [ int ] −9,223,372,036,854,775,807 9,223,372,036,854,775,807
unsigned long long [ int ] 0 18,446,744,073,709,551,615

补充:C/C++支持有符号和无符号,Java只支持有符号

无符号数的编码


B2Uw(x)
函数把一个位向量变成10进制数

无符号数的最大值为:

所以无符号的取值范围是

补码编码

计算机表示负数通常是补码形式


B2Tw(x)
把一个有符号的二进制装换成10进制

一个二进制除了符号位把剩下的位取反得到反码,再在末尾+1,得到补码
比如:1011

  1. 除了符号位取反:1100
  2. 末尾+1:1101
  3. 符号数决定这个数字是负数,后三位决定这个数的绝对值大小为5
  4. 那么这个数为-5
    补码编码的取值范围为:

由于0是属于非复数的那么,表示正数的数就少了一个

机器数用补码表示的好处:

原码简单,适用于乘除运算,但用原码表示的数进行加减法运算比较复杂。
补码,减法运算可以用加法来实现,例如 [X-Y]补 = [X]补 +[-Y]补,
而且,数的符号位也可以参与运算,便于运算结果的正负及是否溢出判断。
因此在计算机中大都采用补码来进行加减及乘除运算。
(不仅是整数,小数亦可用补码表示)

确定大小的整数类型

有某个确定大小的表现编码据类型非常重要
例如
让数据类型与协议指定的数据类型兼容是非常重要的

Java要求补码表示,取值与《64位机器上C语言的整数数据类型的典型取值范围 》一样。单字节用byte,没有long long。

反码与补码

反码公式

补码公式

有符号与无符号间的转换

C语言中将short int 转换成unsight short,会改变数值而不改变位模式
比如
-12345(补码) 二进制:1100 1111 1100 0111
转换成无符号
53191(无符号) 二进制:1100 1111 1100 0111

有符号转换无符号

无符号装换有符号

总的来说对于w位的数字

  • 有符号变无符号
    • 正数不变
    • 负数会加上2^w
  • 无符号变有符号
    • 如果数字小于2^(w-1),不变
    • 如果数字大于2^(w-1),减2^w

运算时,运算符两边如果一个是有符号数,一个是无符号数,那么有符号数会自定转换成无符号.这种转换在逻辑运算中将显得不直观

扩展一个数字的位表示
  • 将一个无符号的数转换成一个跟大范围的数据类型,只要在开头加0,这种运算叫零扩展
  • 将补码数字扩展一个更大范围的数据类型,只要在前面添加最高有效位的值的副本,即最高位为0就添0为1就添1.
    • 比如1010 四位的数字扩展到6位就是111010
  • 对于将short类型数字变成unsigned int 时,先改变大小再从有符号变成无符号
截断数字


无符号数如果经过运算变成负数,在计算机中会被认为是一个很大的无符号数.这种特性可能成为计算机的安全隐患.为了防止这种问题,绝不使用无符号



来自为知笔记(Wiz)


Tags: 计算机系统   计算机   计算   系统   理解计算机