【信息表示】数值

本节研究信息表示中关于数值的相关问题;

字节序和地址增长方向栈中变量

代码片段如下:

int x = 0x10203040; char* p = (char*)&x;printf("%p %p %p\n", &x, p, &p); printf("%x %p %p\n", p[0], &p[0], p); printf("%x %p %p\n", p[1], &p[1], p+1); printf("%x %p %p\n", p[2], &p[2], p+2); printf("%x %p %p\n", p[3], &p[3], p+3);输出如下:0xbfee6bac 0xbfee6bac 0xbfee6ba840 0xbfee6bac 0xbfee6bac30 0xbfee6bad 0xbfee6bad20 0xbfee6bae 0xbfee6bae10 0xbfee6baf 0xbfee6baf

示意图如下:

说明几点:

(1)linux中栈内存地址变量为地址增长方向为向下;

(2)linux中字节序为小端,因为int x的低数据0x40位在最低地址0xbff7cccc上;

数据区中变量

代码片段如下:

int x = 0x10203040;char* p = (char*)&x; int main(void){ printf("%p %p %p\n", &x, p, &p); printf("%x %p %p\n", p[0], &p[0], p); printf("%x %p %p\n", p[1], &p[1], p+1); printf("%x %p %p\n", p[2], &p[2], p+2); printf("%x %p %p\n", p[3], &p[3], p+3);return 0;}输出如下:0x8049810 0x8049810 0x804981440 0x8049810 0x804981030 0x8049811 0x804981120 0x8049812 0x804981210 0x8049813 0x8049813示意图如下:

说明几点:

(1)linux中栈内存地址变量为地址增长方向为向上;

(2)linux中字节序为小端,因为int x的低数据0x40位在最低地址0x9049810上;

(3)其实堆的地址增长方向也为向上;

移位

(1)对于有符号数的移位称为算术移动,无符号数的移位成为逻辑移动;

(2)无论是有符号数还是无符号数,逻辑左移和算术左移的规则是一样的:符号位(最高位)由次高位补位,最低位依次补0;

(3)有符号数, 算术右移时:符号位(正数补0,负数补1)会依次高位补位;无符号数,逻辑右移时,高位补0;

代码片段如下:

int x = 0x7FFFFFFF; cout << hex << x << endl; cout << dec << x << endl; x <<= 1; cout << hex << x << endl; cout << dec << x << endl;

输出如下:

7fffffff2147483647fffffffe-2说明几点

(1)有符号正数左移,验证该代码可得:初始值时x为最大的正数7fffffff,,即十进制2147483647;x向左移1位后,x变为0xfffffffe(补码表示),变为负数-2;

代码片段如下:

int x = 0x80000001; cout << hex << x << endl; cout << dec << x << endl; x <<= 1; cout << hex << x << endl; cout << dec << x << endl;输出如下:80000001-214748364722

说明几点

(1)有符号负数左移,验证该代码可得:初始值时x为负数0x80000001(补码表示),即十进制-2147483647;x向左移1位后,x变为0x2,十进制2;

代码片段如下:

int x = 0x80000000; cout << hex << x << endl; cout << dec << x << endl; x >>= 1; cout << hex << x << endl; cout << dec << x << endl; x >>= 1; cout << hex << x << endl; cout << dec << x << endl;输出如下:80000000-2147483648c0000000-1073741824e0000000-536870912说明几点:

(1)有符号负数右移,验证该代码可得:初始值时x为负数(0x80000000),即十进制-2147483648;x向右移1位后,x变为0xc0000000,十进制-1073741824;x继续向右移1位后,x变为e0000000,十进制-536870912;

代码片段如下:

unsigned int x = 0x80000000; cout << hex << x << endl; cout << dec << x << endl; x >>= 1; cout << hex << x << endl; cout << dec << x << endl; x >>= 1; cout << hex << x << endl; cout << dec << x << endl;输出如下:80000000214748364840000000107374182420000000536870912

说明几点:

(1)无符号负数右移,验证该代码可得:初始值时x为无符号数(0x80000000),即十进制2147483648;x向右移1位后,x变为40000000,十进制1073741824;x继续向右移1位后,x变为20000000,十进制536870912;

溢出问题正上溢

代码片段如下:

int a = 0x7fffffff; int b = 1; unsigned int c = a + b; //内存中二进制位的表示 int d = a + b; cout << hex << a << " " << b << " " << c << " " << d << endl; cout << dec << a << " " << b << " " << c << " " << d << endl;输出如下:7fffffff 1 80000000 800000002147483647 1 2147483648 -2147483648

说明几点:

(1)正上溢:a和b均为有符号正数,采用补码运算法则得到a+b=0x80000000,c,d和的指只是对内存中的二进制位的解释,c为无符号数,为2147483648;而d为有无符号数,为-2147483648;

负上溢敏而好学,不耻下问。

【信息表示】数值

相关文章:

你感兴趣的文章:

标签云: