浮点数格式
32位:seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
1位s表示符号S 0或1
8位e表示2的指数E 二进制小数乘2或者出2就是小数点右移或左移
23位m表示小数部分M 二进制小数
(-1)^S * 2 ^ (E-127) * 1.M
1.将十进制小数转换为二进制小数。
2.将二进制小数的小数点左移或者右移(等价于除2或者乘2),为了保持值不变,指数E加一或者减一。最后得到1.mmmmmmmmmmmmmmmmmmmmmmm
3.E+=127;
4.根据浮点数正负,S设定为0或者1;
特殊:
E全0:表示0.0
E全1:表示无穷
十进制小数转二进制
整数部分十进制转二进制:略
小数部分十进制转二进制:
while(小数部分!=0)
小数部分*=2
if(溢出)
记录二进制小数1
else
记录二进制小数0
举例:0.3
0.3*2=0.6 0
0.6*2=1.2 1
0.2*2=0.4 0
0.4*2=0.8 0
0.8*2=1.6 1
0.6*2=1.2 1
0.2*2=0.4 0 //此处开始循环
得0.3 = 0.010011001001100110011001100110011001100110011(此处0011无限循环)
为什么这样可以表示一个范围内的浮点值
...
[1,2)*2^-2 = [0.25,0.5)
[1,2)*2^-1 = [0.5,1)
[1,2)*2^0 = [1,2)
[1,2)*2^1 = [2,4)
[1,2)*2^2 = [4,8)
[1,2)*2^3 = [8,16)
[1,2)*2^4 = [16,32)
[1,2)*2^5 = [32,61)
...
#include <iostream>
using namespace std;
struct floatModel {
bitset<1> s;//符号位
bitset<8> e;//指数位
bitset<23> m;//小数位
bitset<32> f;//符号指数小数聚合存储位
int float_raw;//f.to_ulong()
float& float_value = (float&)float_raw;
void calc_f() {
//聚合符号位指数位小数位seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
f = s.to_ulong() << 31 | e.to_ulong() << (30 - 7) | m.to_ulong();
float_raw = f.to_ulong();//存储到整型raw中
}
void print(ostream& out) {
calc_f();
out.flags(ios::left);
out << setprecision(50) << setw(50) << float_value << " "
<< f << endl;
}
};
int main() {
floatModel fm = { 0, 127, 1 };
fm.e = 127;//2^0
for (int i = 0; i < (1 << 23); i += (1 << 0)) {//小数按照最小增量递增
fm.m = i;
fm.print(cout);
}
return 0;
/*
1 00111111100000000000000000000000
1.00000011920928955078125 00111111100000000000000000000001
1.0000002384185791015625 00111111100000000000000000000010
1.00000035762786865234375 00111111100000000000000000000011
1.000000476837158203125 00111111100000000000000000000100
1.00000059604644775390625 00111111100000000000000000000101
1.0000007152557373046875 00111111100000000000000000000110
1.00000083446502685546875 00111111100000000000000000000111
1.00000095367431640625 00111111100000000000000000001000
1.00000107288360595703125 00111111100000000000000000001001
1.0000011920928955078125 00111111100000000000000000001010
1.00000131130218505859375 00111111100000000000000000001011
1.000001430511474609375 00111111100000000000000000001100
1.00000154972076416015625 00111111100000000000000000001101
1.0000016689300537109375 00111111100000000000000000001110
1.00000178813934326171875 00111111100000000000000000001111
1.0000019073486328125 00111111100000000000000000010000
1.00000202655792236328125 00111111100000000000000000010001
1.0000021457672119140625 00111111100000000000000000010010
1.00000226497650146484375 00111111100000000000000000010011
1.000002384185791015625 00111111100000000000000000010100
1.00000250339508056640625 00111111100000000000000000010101
1.0000026226043701171875 00111111100000000000000000010110
1.00000274181365966796875 00111111100000000000000000010111
1.00000286102294921875 00111111100000000000000000011000
1.00000298023223876953125 00111111100000000000000000011001
1.0000030994415283203125 00111111100000000000000000011010
1.00000321865081787109375 00111111100000000000000000011011
*/
}