浮点数内存分布:C语言 浮点数存储一、浮点数的三部分结构一个浮点数在内存中被拆成三段从高位到低位依次排列---------------------------------------------------------------------------│S│ │ E │ │ M │---------------------------------------------------------------------------符号位 指数位 尾数位S —— 符号位表示这个数的正负。E —— 指数位控制数值的大小范围。M —— 尾数位控制数值的精度有效数字。二、float 与 double 的位数分配类型S 符号位E 指数位M 尾数位总位数字节数float1 位8 位23 位32 位4 字节double1 位11 位52 位64 位8 字节float 中E 有 8 位M 有 23 位一共有 32 位4 字节。double 中E 有 11 位M 有 52 位一共有 64 位8 字节。三、举例3.14float① 先转化为二进制3.14 → 11.0010001111010111…② 再获取指数位并转化为科学计数取指数 E 1把二进制写成1.xxx × 2^E的形式11.0010001111010111… 1.10010001111010111… × 2^1└────────────────────────┘这就是尾数M③ 处理 E 值加上偏移量若为 floatE 127若为 doubleE 1023则 E 1 → 1 127 128转换为二进制10000000④ 计算公式(-1)^S × 2^E × (M 1)得出 3.14 的存储为SE8 位M23 位01000000010010001111010111000010完整 32 位0 10000000 10010001111010111000010四、同理-20.17double存储为SE11 位M52 位1100000000110100001010111000010100011110101110000101000111101100完整 64 位1 10000000011 0100001010111000010100011110101110000101000111101100S E M五、步骤小结把十进制数转成二进制写成1.xxx × 2^E的科学计数形式取出指数 E 和尾数 M根据类型给 E 加偏移量float 加 127double 加 1023并转成对应位数的二进制把 S、E、M 按顺序拼起来得到最终存储结果六、生成float和double的流程示范代码#include stdio.h int main() { while(1){ int isDouble; printf(double为1float为0请输入); scanf(%d, isDouble); double num; printf(请输入浮点数); scanf(%lf, num); int S[1]; // 符号位Signfloat和double均为1位 int E[11]; // 指数位Exponentfloat为8位double为11位 int M[52]; // 尾数位Mantissafloat为23位double为52位 int s, e, m; if (isDouble){ s 1; e 11; m 52; }else{ s 1; e 8; m 23; } // 生成对应分布示意图 // 符号位 if (num 0){ S[0] 1; num -num; }else{ S[0] 0; } // 整数处理 int numIntegral num; int intArr[10000]; int intNumTemp 10000; for (int i 0; i 10000; i){ // 指数位数组倒序存储 if (numIntegral 0){ intNumTemp i; break; } intArr[i] numIntegral % 2; numIntegral / 2; } // 小数处理 double numFractional num - (int)num; int fracArr[10000]; int fracNumTemp 10000; for (int i 0; i 10000; i){ // 指数位数组正序序存储 numFractional * 2; fracArr[i] (int)numFractional; if (fracNumTemp i (int)numFractional 0){ fracNumTemp i 1; } numFractional - fracArr[i]; } // 指数位处理 int eTemp; if (intNumTemp 0){ eTemp intNumTemp - 1; }else{ eTemp 0 - fracNumTemp; } if (isDouble){ eTemp 1023; }else{ eTemp 127; } for (int i 0; i e; i){ E[i] eTemp % 2; eTemp / 2; } // 尾数位处理 int ind 0; for (int i intNumTemp - 2; i 0 ind m; --i){ M[ind] intArr[i]; } for (int i intNumTemp 0 ? 0 : 1 - eTemp; ind m; i){ M[ind] fracArr[i]; } // 输出示意图 printf(%d , S[0]); for (int i e - 1; i 0; --i){ printf(%d, E[i]); } printf( ); for (int i 0; i m; i){ printf(%d, M[i]); } printf(\n); } return 0; }