huangyushun 发表于 2020-3-27 22:39:08

浮点数float和double内存存储方式解析学习_C++编程实现验证记录!!!

主要就是发个帖在PYG存档下学习记录:
浮点数是学C那会的基础类型里最恐惧的东西,两年前硬着头皮把float的解析写了一下,
代码渣的不行...
如下:

class float类
{
/*
float浮点数在内存的存放方式:
bit 31符号位 1位
bit 30-23 指数位 8位
bit 22-0 尾数位 23位
*/
public:
float类(float 参数) { 浮点数 = 参数; 初始化(); };
void 设置浮点数(float 参数) { 浮点数 = 参数; 初始化(); };
float 获取浮点数() { return 浮点数; };

//如果是负数返回真,否则返回假
bool 拆分浮点数(int *整数, float *小数) {

int 整数位数 = 指数 - 127;
int 位记录 = 22;
*整数 = 0;
*小数 = 0.0f;
if (!整数位数)
{
   *整数++;
}
else if (整数位数 > 0)
{
   //整数
   *整数 += 指数运算(2, 整数位数);   
   for (int i = 整数位数; i > 0; i--)
   {
    二进制数 = *浮点指针 >> 位记录--;
    if (二进制数) { *整数 += 指数运算(2, i - 1); }
   }
   //小数
   for (int i = 位记录; i >= 0; i--)
   {
    二进制数 = *浮点指针 >> i;
    if (二进制数) { *小数 += 指数运算(2, -(位记录 - i + 1)); }
   }
}
else
{
   //整数为0的小数
   *小数 += 指数运算(2, 整数位数);
   for (int i = 位记录; i >= 0; i--)
   {
    二进制数 = *浮点指针 >> i;
    if (二进制数) { *小数 += 指数运算(2, -(位记录 - i - 整数位数 + 1)); }
   }
}
return 符号;
};

//二进制位
unsigned int 符号 : 1;
unsigned int 指数 : 8;
unsigned int 尾数1 : 1;
unsigned int 尾数2 : 1;
unsigned int 尾数3 : 1;
unsigned int 尾数4 : 1;
unsigned int 尾数5 : 1;
unsigned int 尾数6 : 1;
unsigned int 尾数7 : 1;
unsigned int 尾数8 : 1;
unsigned int 尾数9 : 1;
unsigned int 尾数10 : 1;
unsigned int 尾数11 : 1;
unsigned int 尾数12 : 1;
unsigned int 尾数13 : 1;
unsigned int 尾数14 : 1;
unsigned int 尾数15 : 1;
unsigned int 尾数16 : 1;
unsigned int 尾数17 : 1;
unsigned int 尾数18 : 1;
unsigned int 尾数19 : 1;
unsigned int 尾数20 : 1;
unsigned int 尾数21 : 1;
unsigned int 尾数22 : 1;
unsigned int 尾数23 : 1;
private:
float 浮点数;
int *浮点指针 = (int *)&浮点数;
unsigned int 二进制数 : 1;
float 指数运算(int 整数, int 指数)
{
int 指数绝对值; int 结果 = 整数;
if (!整数) { return 0.0f; }
if (!指数) { return 1.0f; }
指数 > 0 ? 指数绝对值 = 指数 : 指数绝对值 = -指数;
if (指数绝对值 == 1) { return 指数 > 0 ? 结果 : 1.0f / 结果; }
for (size_t i = 指数绝对值; i > 1; i--) { 结果 *= 整数; }
return 指数 > 0 ? 结果 : 1.0f / 结果;
}
void 初始化()
{
符号 = *浮点指针 >> 31;
指数 = *浮点指针 >> 23;
尾数1 = *浮点指针 >> 22;
尾数2 = *浮点指针 >> 21;
尾数3 = *浮点指针 >> 20;
尾数4 = *浮点指针 >> 19;
尾数5 = *浮点指针 >> 18;
尾数6 = *浮点指针 >> 17;
尾数7 = *浮点指针 >> 16;
尾数8 = *浮点指针 >> 15;
尾数9 = *浮点指针 >> 14;
尾数10 = *浮点指针 >> 13;
尾数11 = *浮点指针 >> 12;
尾数12 = *浮点指针 >> 11;
尾数13 = *浮点指针 >> 10;
尾数14 = *浮点指针 >> 9;
尾数15 = *浮点指针 >> 8;
尾数16 = *浮点指针 >> 7;
尾数17 = *浮点指针 >> 6;
尾数18 = *浮点指针 >> 5;
尾数19 = *浮点指针 >> 4;
尾数20 = *浮点指针 >> 3;
尾数21 = *浮点指针 >> 2;
尾数22 = *浮点指针 >> 1;
尾数23 = *浮点指针 >> 0;
};
};


今天有网友提及,然后发了这个给他...
然后聊到double,郁闷,跟float还略有不同,又折腾了一天,做个记录,发pyg存个
代码如下:

//如果是负数返回真,否则返回假_整数部分不能超过10位10进制数
bool 浮点数拆分(double 浮点数, int* 整数, double* 小数)
{
//类型         符号位         指数位             尾数位
//floa(32bit) 最左侧(第31位) 第30-23位(占8bit) 第22-0位(占23bit)
//double(64bit) 最左侧(第63位) 第62-52位(占11bit) 第51-0位(占52bit)
llong 浮点数据 = *(llong*)&浮点数;
unsigned int 指数 = (浮点数据 >> 52) & 0x7FF;
int 整数位数 = 指数 - 0x3FF;
int 位记录 = 51;//0-52是位数51是最高位
unsigned int 二进制数;
int 位开始 = 0;
//初始化
*整数 = 0;
*小数 = 0.0;
//如果整数部分是0的话_不用进来了
if (整数位数 >= 0)
{
*整数 += 1 << 整数位数;
for (int i = 整数位数; i > 0; i--)
{
   二进制数 = 浮点数据 >> 位记录--;
   if (二进制数 << 31) {
    *整数 += 1 << i - 1;
   }
}
整数位数 = 位记录 > 30 ? 30 : 位记录;
}
else
{
//整数部分为0的话_指数为负数
//而这个负数刚好是开始计算的位置
位开始 = -整数位数;
*小数 += 1.0 / (1 << 位开始);
整数位数 = 30 - 位开始;
}
//*小数 = 浮点数 - *整数;
for (int i = 位开始; i <= 整数位数; i++)
{
二进制数 = 浮点数据 >> 位记录--;
if (二进制数 << 31) { *小数 += 1.0 / (1 << (i + 1)); }
}
//小数精度16位
//1.1234567891234568
return 浮点数据 >> 63;
}


不破不立 发表于 2020-3-28 11:08:11

坐沙发,学习,收藏备用。

lhglhg 发表于 2020-3-29 10:12:29

收藏备用。

BOOMARRY 发表于 2020-3-31 14:27:26

什么版本VS支持中文函数名?

快乐狼 发表于 2020-4-1 21:46:46

跟着一起学习啦&#128513;

superroshan 发表于 2020-4-19 22:08:59

c语言是我抹不去的痛还是要努力学习去掌握它
页: [1]
查看完整版本: 浮点数float和double内存存储方式解析学习_C++编程实现验证记录!!!