#include
int main()
{
int x = -1;
unsigned u = 2147483648;
printf("x=%u=%d\n", x, x);
printf("u=%u=%d\n", u, u);
return 0;
}
运行结果:
x=4294967295=-1
u=2147483648=-2147483648
int型整数为32位带符号整数,当把x
作为无符号整数解释时,如下:
-1的补码表示形式为:
2^n - 1 = 2^32-1 = 11111111 11111111 11111111 11111111
当作为无符号整数进行解释时,其值为4294967295
当我们把无符号整数当作int型整数进行处理时:
2147483648的二进制表示形式为10000000000000000000000000000000,当我们把它当成带符号数来解释时,他的真值就是10000000000000000000000000000000 - 2^32 = -2147483648
以上计算根据为下图中的补码和原码之间的关系:
看下面这段代码:
#include
int main()
{
if(-2147483648 < 2147483647)
printf("True\n");
else
printf("False\n");
printf("------------------\n");
printf("------------------\n");
if(-2147483648-1 < 2147483647)
printf("True\n");
else if(-2147483648-1 == 2147483647)
printf("-2147483648-1 == 2147483647\n");
else
printf("false\n");
return 0;
}
按照C90
标准进行编译
编译命令:
gcc --std=c90 test.c -o test.exe
运行结果为:
False
------------------
------------------
-2147483648-1 == 2147483647
首先我们来看第一个if语句:
计算机在处理该语句的时候-
和后面的字面量是分开处理的,他要先根据后面字面量的值来判断其数据类型,判断根据就是上面的那张表,2147483648是2^31,属于unsigned int
类型,后面的数是2^23-1
,属于int
类型,当int
和unsigned int
进行比较时,按照unsigned int
进行比较,显然前者大于后者,故第一个判断语句为False
再来看第二个判断语句:
其实分析过程和上面是一样的,在C90
标准下,2^31
总是会被当作unsigned int
类型的整数来处理,一旦它被当作无符号类型的整数,前面的-
也就失去了意义,所以第二条判断的结果是两者相等
按照C99
标准进行编译
gcc -std=c99 test.c -o test.exe
运行结果为:
True
------------------
------------------
True
2147483648被判断为long long
类型,为带符号整型,因此被正确解释成负数,判断结果也跟预期一样
IEEE 754标准
规定尾数的小数点前1位为1,省略不写,单精度占23位,双精度占52位
移码表示阶码,规定为2^n-1 - 1
,单精度双精度分别占8位和11位
利用union
的数据成员共用一段内存的特性检测机器为大端还是小端
大端就是最高有效位存储在低地址上
小端就是最高有效位存放在高地址上
检测代码:
#include
void main()
{
union NUM
{
int a;
char b;
} num;
num.a = 0x12345678;
if(num.b == 0x12)
printf("Big Endian\n");
else
printf("Little Endian\n");
printf("num.b = %x\n", num.b);
return 0;
}