数据的表示
来源:互联网 发布:win系统传文件到mac 编辑:程序博客网 时间:2024/05/22 17:16
1、关于进制
十进制
0
1
2
3
4
5
6
7
八进制
0
1
2
3
4
5
6
7
十六进制
0
1
2
3
4
5
6
7
二进制
0000
0001
0010
0011
0100
0101
0110
0111
十进制
8
9
10
11
12
13
14
15
八进制
10
11
12
13
14
15
16
17
十六进制
8
9
A
B
C
D
E
F
二进制
1000
1001
1010
1011
1100
1101
1110
1111
2、字
每台计算机都有一个字长(word size),指明整数和指针数据的标称大小(nominal size)。因为虚拟地址是以这样的一个字来编码的,所以字长决定了系统中虚拟地址空间的大小。
3、数据大小
C语言中不同的数据类型分配的字节数依赖于机器和编译器。下表是32位和64位机器的典型值。
C声明
32位机器
64位机器
char
1
1
short int
2
2
int
4
4
long int
4
8
long long int
8
8
char *
4
8
float
4
4
double
8
8
long double
4、寻址和字节顺序
对于跨越多字节的程序对象,需建立两规则:这个对象的地址是什么,如何在存储器中排列这些字节。在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中最小的地址。排列表示一个对象的字节有两个通用的规则:最低有效字节在最前面的方式,称为小端法(little endian);最高有效字节在最前面的方式,称为大端法(big endian);
假设变量x类型为int,位于地址0x100处,它的十六进制表示为0x01234567。地址范围为0x100~0x103的字节,其排列顺序依赖于机器的类型。
小端法
地址
...
0x100
0x101
0x102
0x103
...
数据
...
67
45
23
01
...
大端法
地址
...
0x100
0x101
0x102
0x103
...
数据
...
01
23
45
67
...
typedef unsigned char *byte_pointer;
//=========================================
// 显示不同类型对象的字节表示
//=========================================
void show_bytes(byte_pointer start, int len)
{
for (int i = 0; i < len; i++)
printf(" %.2x", start[i]);
printf("\n");
}
void show_int(int x)
{
show_bytes((byte_pointer)&x, sizeof(int));
}
void show_float(float x)
{
show_bytes((byte_pointer)&x, sizeof(float));
}
void show_pointer(void *x)
{
show_bytes((byte_pointer)&x, sizeof(void *));
}
对指针的类型强制转换不会改变真实的指针,只是告诉编译器以新的数据类型来看待被指向的数据。
5、布尔代数
~
&
0
1
|
0
1
^
0
1
0
1
0
0
0
0
0
1
0
0
1
1
0
1
0
1
1
1
1
1
1
0
布尔环(Boolen ring)
a ^ a = 0 ===> (a ^ b) ^ a = b在许多应用中可以使用该属性。
void inplace_swap(int *x, int *y)
{
*y = *x ^ *y;
*x = *x ^ *y;
*y = *x ^ *y;
}
6、整形的表示
6.1、无符号数的编码
假如一个整数类型的数据有w为,我们可以将位向量写成,表示整个向量,或者写成,表示向量中的每一位。把看做一个二进制表示的数,就获得了的无符号表示。用函数B2Uw(Binary to Unsigned)来表示:
无符号数的二进制表示有一个很重要的属性,就是每个介于0~2w-1之间的数都有唯一一个w位的值编码。函数B2Uw 是一个双射(bijection)。
6.2、补码编码
最常见的有符号数的计算机表示方式就是补码(two’s-complement)形式在这个定义中,将字的最高有效位解释为负权(negative weight)。用函数B2Tw(Binary to Two’s-complement)来表示:
最高有效位xw-1也称为符号位,它的权重为-2w-1。符号位设置为1时,表示值为负,而当设置为0时,值为非负。函数B2Tw是一个双射,每个介于-2w-1~2w-1-1之间的数都有唯一一个w位的值编码。补码的范围是不对称的:。
6.3、有符号数的其他表示方法
反码(Ones’ Complement):除了最高有效位的权是-(2w-1-1)而不是-2w-1,其它和补码一样的:
源码(Sign-Magnitude):最高有效位是符号位,用来确定剩下的位应该取负权还是正权:
这两种表示方法都有一个奇怪的属性,即对于数字0都有两种不同的编码方式。
6.4、有符号数和无符号数之间的转换
对于多数C语言的实现而言,处理同样字长的有符号数和无符号数之间的相互转换的一般规则是:数值可能会变,但是位模式不变。
有符号转换成无符号:
无符号转换成有符号:
6.5、扩展一个数字的位表示
无符号的数采用零扩展(zero extension),补码的数采用符号扩展(sign extension)。
补码(有符号的数)满足下列等式:
6.6、截断数字
无符号数的截断结果是:
补码数字的截断结果是:
7、整形运算
7.1、无符号的加法
无符号的运算可以被视为一种模运算形式。
定义参数x与y的运算如下:
判断无符号数x与y相加是否溢出的C函数:
int uadd_ok(unsigned int x, unsigned int y)
{
unsigned int sum = x + y;
return sum > x;
}
7.2、补码的加法
定义参数x与y的运算如下:
两个数的w位补码之和与无符号之和有完全相同的位级表示。
判断补码数x与y相加是否溢出的C函数:
int tadd_ok(int x, int y)
{
int sum = x + y;
int neg_over = x < 0 && y < 0 && sum >= 0;
int pos_over = x > 0 && y > 0 && sum > 0;
return !neg_over && !pos_over;
}
7.3、无符号的乘法
W位无符号乘法运算的结果为:
7.4、补码的乘法
w位补码乘法运算的结果为:
乘法运算的位级表示都是一样的。也就是,给定长度为w的位向量和,无符号乘积的位级表示补码乘积的位级表示是相同的。
7.5、乘以常数与除以2的幂
由于整数乘法比移位和加法的代价要大得多,许多C编译器试图以移位、加法和减法的组合来消除很多整数乘以常数的情况。
整数的除法,当需要舍入时,采用向零取整的方法,而算法右移的结果,相当于向下取整。当和,整数除法的结果是(向上取整),与右移的(向下取整)不同,因此在移位之前可以利用下面属性对x进行“偏置”(biasing)。
对于整数和任意,有
对于使用算术右移的补码机器,C表达式:
(x < 0 ? (x + (1<<k)-1) : x) >> k
总结
计算机执行的“整数”运算实际上是一种模运算形式。表示数字的有限字长限制了可能的值的取值范围,结果运算可能溢出。补码表示提供了一种既能表示负数又能表示正数的灵活方法,同时使用了与执行无符号算术相同的位级实现,这些运算包括加法、减法、乘法、甚至除法,无论运算数是以无符号形式还是以补码形式表示,都有完全一样或者非常类似的位级行为。
- 数据的编码表示
- 数据的表示方法
- 数据的单位表示
- 数据的表示
- 推荐数据的表示
- 数据的表示总结
- 数据表示的要素
- 计算机中数据的表示
- bfd的后端数据表示
- 1.3 数据的表示方法
- J2EE架构的数据表示
- 数据的表示和运算
- 海量数据-整数的表示
- float数据的内存表示
- 数据的表示____浮点
- 打印数据的二进制表示
- 多视点的数据表示
- Highcharts的数据表示(1)
- CentOS-6.3安装配置JDK-7
- UVa 1587 - Box
- day54,page70
- Qt音乐播放器制作(一)Easy Player
- CSS学习笔记01-块元素和内联元素.html
- 数据的表示
- Spring4.x IOC容器的初始化,开启log4j日志
- hadoop2.4.0 安装配置
- UVA - 10054 The Necklace
- uva10131
- C语言malloc和free
- 7.Eclipse中创建新Maven项目
- CSS学习笔记02-定位和浮动.html
- uva 10131(最长递增子序列)