关于C语言的浮点数的思考和小实验
C语言浮点数有 float 和 double 。
浮点数在内存中的组成存放形式为 : 符号 s + 阶码 E +尾数 M 。其中 s 确定正负,E确定每一位的权重,M为未加权重的各位编码。
float 中 s 一位, E 的位数 k =8 , M 的位数 f =23 .
数值 = (-1) ^ s * 2^(E - bias) * (1+M) 。
其中 bias = 2^(k-1)-1 ,E - bias 可使指数的范围在 -126 ~ 127 之间(小于 1 小数).
尾数 M 仅为小数部分,小数点位于M之前。小数点前省略了 1 .
例: float 5.0 =
0 10000001 01000000000000000000000 = 40 a0 00 00 H .
= ( -1 ) ^ 0 * 2 ^ ( 129 - 127 ) * (1+0.25 ) = 5.0 。
在 C 语言中 若进行 整型和浮点型之间的转化,gcc 编译器是进行的对应值的转换。而并不是将二进制编码以另一张数据类型 “ 解释 ”。
即 ,int 5 转变为了 float 5.0 ,他们的二进制编码是变化了的。
如:
int 5 = 0B 00000000 00000000 00000000 00000101 = 5H
float 5.0 = 0B 01000000 10100000 00000000 00000000 = 40 a0 00 00H
若此二进制编码直接以对应类型 “ 解释 ” ,得出的值无意义。因为它们的编码方式是不一样的。
1 #include <stdio.h> 2 #include <stdlib.h> 3 ch[4]={0x00,0x00,0xa0,0x40}; 4 5 int main(){ 6 unsigned int a=5; 7 unsigned char *p=&a; 8 float*f=&a; 9 int i; 10 for(i=0;i<4;i++){ //被一个错误困了很久,最后发现for循环内的代码错了,导致指针运算错误。 11 12 *(p+i)=ch[i]; 13 printf("%x\n",*p); 14 15 }; 16 17 18 19 printf("%f\n",*f); 20 21 return 0; 22 23 }
上述代码为通过指针改变 int 的值 并通过一个 float * 指针将其表示为一个 float 数据。(实际并无卵用)