C语言的数据类型大体上分为整数和浮点数两种类型。因为char和指针类型实际上都是整数类型。
移码:给每一个数值加上一个偏置常数即可。通常是加上2^(n-1)或者是2^(n-1)-1这里的n通常取编码的位数 (IEEE 754)
移码通常用来表示浮点数的阶,这样便于浮点数加减运算时对阶的操作。
机器数是指补码,真值则是这个数原来的十进制形式。
变形补码:补码的符号位只有一位,容易溢出。所以便有了变形补码,它的符号为有两位,不会溢出。
正数的原码=反码=补码
负数的反码是对其原码按位取反,补码=反码+1.
在C语言中整数又可分为无符号整数和带符号整数两类。即unsigned和signed。
无符号整数在机器中直接以二进制补码的形式存放(因为正数的原码=补码,所以也可认为是原码),现代的机器大多是从左到右对应于从高到低。例如8051就是这样的。故C语言的无符号类型数的范围如下:(32位下)
unsigned char (1字节) 0——255
unsigned int (4字节) 0——4294967296
unsigned short(2字节) 0——65535
unsigned long(4字节) 0——4294967296
带符号整数在机器中也是以二进制补码形式存放的, 最高位是符号位,其余是数值位。但是有个例外,2147483648他的补码是这样的110000000000000000000000000000000 (33位数字),我们说最高位是符号位,所以反码应该是101111111111111111111111111111111(33位数字),只有这样才保证没有溢出,所以实际上计算机还是自动往前多读了一位,否则就会解释为0.
char -128——127
int -2147483647 - 1 —— 2147483647
long long -9223372036854775807- 1 ——9223372036854775807。
数字 2147483648 大于最大整数值 2147483647,而且-2147483648 分两步解释,首先2147483648是个无符号正数,由于它大于2147483647,所以类型被取为unsigned long。在VS上给unsigned类型不允许使用一元负运算符。故定义为-2147483647-1。这样使得类型是int类型。
浮点数的表示不同于整数(整数是定点数)。表示起来很麻烦。float,double,long double。
第0位是符号位,0表示正数,1表示负数。阶码是由移码表示的,故为2^7 = 128。故
最大正数应该表示为:0.111111111111111111111111×2^127=(1-2^-24)×2^127
最小正数应该表示为:0.1000000000000000000000000×2^-128=2^-129
最小负数应该表示为:-0.111111111111111111111111×2^127=-(1-2^-24)×2^127
最大负数应该表示为:-0.1000000000000000000000000×2^-128=-2^-129
0还是表示为0
用这种表示方式,使得可表示的数的范围变得非常大。但是不是绝对精确的。而且早期的这个表示方式的规定不是统一的,直到IEEE 754制定,计算机中浮点数的表示才算统一了标准。该标准规定了整数部分为1(小数点前隐含了1),32位的阶码有8位(偏置常量是127),64位的阶码有11位(偏置常量是1023)。因为偏置常量是127,故实际的阶码应该是00000001——10000000.其中没有包含00000000和11111111。所以0在IEEE 754中是这样表示的。+0=00000000000000000000000000000000. -0=10000000000000000000000000000000
所以0在该标准中有两种表示方式。
规定了+∞和-∞。他们在IEEE 754标准中,表示如下:
+∞:01111111100000000000000000000000
-∞:11111111100000000000000000000000
至于为什么说float的精度是小数点后6——7位,这是因为上面的IEEE 754规定了32位下尾数最多有23位,即2^23 = 8388608,刚好是10进制的7位,最多7位,有些7位是不精致的,因为毕竟数值不是9999999,而是8388608.故教科书上写的是6——7位。64位下阶码是11位,符号位是1位,所以尾数占据52位,即2^52 = 4503599627370496.这个数字有16位,当然由于不是9999999999999999,故教科书给的是15——16位。