IEEE754标准
IEEE二进制浮点数算术标准(IEEE 754)规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,一般来说很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
- IEEE754标准中的常用名词
values值的表示
V=(-1)^s*(1+M)*2^(E-127)(单精度) V=(-1)^s*(1+M)*2^(E-1023)(双精度) V:表示的浮点型数据,s表示符号位,M表示尾数,E表示阶码
IEEE754单精度32位
- 表示图表
sign: 符号位, 即图中蓝色的方块,1bit表示,其中0代表为正数,1代表为负数
biased exponent: 偏移后的指数位, 即图中绿色的方块,8bit表示,也就是表示E,即是指数部分
fraction: 尾数位, 即图中红色的方块,23bit表示,也就是表示M,也就是尾数部分
对于32位的IEEE754的移码是127
- 例子
十进制浮点数20.5 = 二进制10100.1
然后, 需要把这个二进制数转换为以2为底的指数形式:
二进制10100.1 = 1.01001 * 2^4
那么S = 0,E = 4 + 127 ,M = b’01001 (二进制表示)
IEEE754双精度64位
- 表示图表
sign: 符号位, 即图中蓝色的方块,1bit表示,其中0代表为正数,1代表为负数
biased exponent: 偏移后的指数位, 即图中绿色的方块,11bit表示,也就是表示E,即是指数部分
fraction: 尾数位, 即图中红色的方块,52bit表示,也就是表示M,也就是尾数部分
对于64位的IEEE754的移码是1023
- 例子
十进制浮点数20.5 = 二进制10100.1
然后, 需要把这个二进制数转换为以2为底的指数形式:
二进制10100.1 = 1.01001 * 2^4
那么S = 0,E = 4 + 1023 ,M = b’01001 (二进制表示)
单精度和双精度数据转IEEE754十六进制的数据c代码
- ieee754.c代码
#include "ieee754.h"
/**
* @brief 将float数据转为IEEE754格式的数据
* @param converData IEEE754数据结构体,传出参数
* @param data 传入的数据
*/
void floatdata2IEEE754(Data2IEEE754* converData,double data) {
int s = 0;//正负
int E = 0;//指数
int i = 0;//用于表征E
int flag = 1;//循环标志位
double M = 0.0;//尾数
double buf = data;//对data数据进行暂存
if (data >= 0) {//为正数
s = 0;
}
else if (data < 0) {//为负数
s = 1;
data = -data;//转为正数
buf = data;
}
while (flag) {
if (data >= 1 && data < 2) {
flag = 0;
break;
}
else if (data >= 2) {
data = data * pow(2, -1);
i++;
}
else if (data < 1) {
data = data * pow(2, 1);
i++;
}
}
if (buf >= 1) {
E = i + 127;
M = buf * pow(2, -i) - 1;
}
else {
E = 127 - i;
M = buf * pow(2, i) - 1;
}
//将转换后的数据存入结构体中
converData->float2IEEE = (int)(s * pow(2, 31)) + (int)(E * pow(2, 23)) + (int)(M * pow(2, 23));
}
/**
* @brief 将double数据转为IEEE754格式的数据
* @param converData IEEE754数据结构体,传出参数
* @param data 传入的数据
*/
void doubledata2IEEE754(Data2IEEE754* converData,double data) {
int s = 0;//正负
int E = 0;//指数
int i = 0;//用于表征E
int flag = 1;//循环标志位
double M = 0.0;//尾数
double buf = data;//对data数据进行暂存
if (data >= 0) {//为正数
s = 0;
}
else if (data < 0) {//为负数
s = 1;
data = -data;//转为正数
buf = data;
}
while (flag) {
if (data >= 1 && data < 2) {
flag = 0;
break;
}
else if (data >= 2) {
data = data * pow(2, -1);
i++;
}
else if (data < 1) {
data = data * pow(2, 1);
i++;
}
}
if (buf >= 1) {
E = i + 1023;
M = buf * pow(2, -i) - 1;
}
else {
E = 1023 - i;
M = buf * pow(2, i) - 1;
}
// 52 - 20 = 32,将M乘上2^20次方
double doubleDataM = M * pow(2, 20);
int Mint = floor(doubleDataM);//获取整数部分
//printf("doubleDataM -- %lf\n", doubleDataM);
double doubleDataM2 = doubleDataM - Mint;//获取小数部分
//printf("doubleDataM2 -- %lf\n", doubleDataM2);
converData->double2IEEEHight = (int)(s * pow(2, 31)) + (int)(E * pow(2, 20)) + Mint;
converData->double2IEEELower = (doubleDataM2 * pow(2, 32));
}
- ieee754.h代码
#ifndef _IEEE754_H
#define _IEEE754_H
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned long
//保存IEEE754格式的数据结构体
typedef struct DATA2IEEE754{
int float2IEEE; //保存float类型转换后的数据
int double2IEEEHight; //保存double类型转换后的高32bit
uint32_t double2IEEELower; //保存double类型转换后的低32bit,注意这里一定需要是无符号类型的数据类型,如果是有符号的话,就会出现问题,因为保存的低32位数据就是无符号,并且无符号可以保存的数据大小更大。
}Data2IEEE754;
void floatdata2IEEE754(Data2IEEE754* converData,double data);
void doubledata2IEEE754(Data2IEEE754* converData,double data);
#endif
代码测试
#include "ieee754.h"
#include <stdio.h>
#include <stdlib.h>
int main() {
Data2IEEE754 a;
floatdata2IEEE754( &a,-487.2988090940904904);
doubledata2IEEE754( &a,-9487.29880909409049040009);
printf("float -----------------\n");
printf("float ----%x\n",a.float2IEEE);
printf("double -----------------\n");
printf("double 高32位----%x\n",a.double2IEEEHight);
printf("double 低32位----%x\n",a.double2IEEELower);
return 0;
}
测试结果
网站显示结果
- 单精度结果
- 双精度结果
附件
- 使用的测试在线工具链接:
- 阅读的文章推荐