IEEE754标准的c语言阐述,以及几个浮点数常量

news/2024/7/27 10:33:30/文章来源:https://blog.csdn.net/weixin_43172531/article/details/136412329

很多年前,调研过浮点数与整数之间的双射问题:
win7 intel x64 cpu vs2013 c语言浮点数精度失真问题

最近重新学习了一下IEEE754标准,也许实际还有很多深刻问题没有被揭示。
计算机程序设计艺术,据说这本书中也有讨论。

参考:https://upimg.baike.so.com/doc/643382-681042.html
在这里插入图片描述
float32在线测试页面 :https://www.h-schmidt.net/FloatConverter/IEEE754.html
在这里插入图片描述
我用手写计算的方式,算过一遍之后,得到一个结论:
任意数值的32bit,对应的float,都可以被精确地计算,转换为一个无误差对应的字符串,且与printf %.Nf一致,只要N足够大。
eg:float FLT_TRUE_MIN == 0x00000001, 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125 (149位小数)
所有其他float都是FLT_TRUE_MIN这个数的整数倍。
稍微计算几个值就明白为什么。fraction中第一个1代表0.5,第二个1是0.25,然后是0.125,0.0625,0.03125 …尾数一直可以被2整除。题外话,如果是前苏联的3进制计算机,可能就存在无限循环除不尽的问题。

但是,前面提过,float与u32的双射问题。
显然32bit最多只有4,294,967,295个值。
u32只有10位十进制数,与149位十进制小数到FLT_MAX(340282346638528859811704183484516925440.000000)是无法一一对应的。
那么中间,绝大多数的浮点数数值都没有32bit的对应值,也就是说,人工随便写的一个浮点数字符串,有99%以上的概率转换为float之后,再转换为string,是无法还原的!
但是,c基础库的printf %f和atof有一种不失真、可逆的转换实现!只是这种实现是从32bit到float string,再还原到32bit。
人为造假float值比较容易被识别,只要是不可逆的就一定是人为改过的!

个人觉得IEEE754标准的设计,c语言的实现,并不是看起来那么简单。
稍微提几个方面:硬件电路、编译器、累计误差…这些方面的坑感觉都很深。

下面是个人测试float的代码及测试结果:

#include <stdio.h>
#include <float.h>
#include <math.h>
union u32f32 {unsigned int u32;float f32;struct {unsigned int fraction : 23;unsigned int exp : 8;unsigned int sign : 1;};
};
static char c_u32[64] = { 0 };
static char c_sign[64] = { 0 };
static char c_exp[64] = { 0 };
static char c_fraction[64] = { 0 };
void to_binary_string_with_spaces(const unsigned int u32, const int bits, char c_temp[64]) {int valid_bits = bits <= 32 ? bits : 32;int char_index = 0;for (int i = valid_bits - 1; i >= 0; i--) {if (i % 4 == 3 && i != valid_bits - 1) {c_temp[char_index++] = ' ';}c_temp[char_index++] = (u32 & (1U << i)) ? '1' : '0';}c_temp[char_index] = '\0';
}
void print_float_binary(const char* p_name, const unsigned int i) {const union u32f32 u32_f32_obj = { .u32 = i };to_binary_string_with_spaces(u32_f32_obj.u32, 32, c_u32);to_binary_string_with_spaces(u32_f32_obj.sign, 1, c_sign);to_binary_string_with_spaces(u32_f32_obj.exp, 8, c_exp);to_binary_string_with_spaces(u32_f32_obj.fraction, 23, c_fraction);printf("float %s == 0x%08x, binary(%s)\n", p_name, u32_f32_obj.u32, c_u32);printf("float %s == 0x%08x, sign(%s)*(-1) 2^exp(%s-127) fraction(1.%s)\n",p_name, u32_f32_obj.u32, c_sign, c_exp, c_fraction);
}
int test_float() {union u32f32 u32_f32_max_obj = { .f32 = FLT_MAX };//3.402823466e+38Funion u32f32 u32_f32_epsilon_obj = { .f32 = FLT_EPSILON };//1.192092896e-07Funion u32f32 u32_f32_min_obj = { .f32 = FLT_MIN };//1.175494351e-38Funion u32f32 u32_f32_true_min_obj = { .f32 = FLT_TRUE_MIN };//1.401298464e-45Funion u32f32 u32_f32_NaN_obj = { .f32 = NAN };//nanunion u32f32 u32_f32_inf_obj = { .f32 = INFINITY };union u32f32 u32_f32_ne_inf_obj = { .f32 = -INFINITY };union u32f32 u32_f32_0_obj = { .f32 = 0 };union u32f32 u32_f32_ne_0_obj = { .f32 = 0,.sign = 1 };printf("float FLT_MAX      == 0x%08x, %f\n", u32_f32_max_obj.u32, u32_f32_max_obj.f32);printf("float FLT_EPSILON  == 0x%08x, %.23f\n", u32_f32_epsilon_obj.u32, u32_f32_epsilon_obj.f32);printf("float FLT_MIN      == 0x%08x, %.126f\n", u32_f32_min_obj.u32, u32_f32_min_obj.f32);printf("float FLT_TRUE_MIN == 0x%08x, %.149f\n", u32_f32_true_min_obj.u32, u32_f32_true_min_obj.f32);printf("float NaN          == 0x%08x, %f\n", u32_f32_NaN_obj.u32, u32_f32_NaN_obj.f32);printf("float INFINITY     == 0x%08x, %f\n", u32_f32_inf_obj.u32, u32_f32_inf_obj.f32);printf("float -INFINITY    == 0x%08x, %f\n", u32_f32_ne_inf_obj.u32, u32_f32_ne_inf_obj.f32);printf("float +0           == 0x%08x, %f\n", u32_f32_0_obj.u32, u32_f32_0_obj.f32);printf("float -0           == 0x%08x, %f\n", u32_f32_ne_0_obj.u32, u32_f32_ne_0_obj.f32);//print_float_binary("FLT_MAX     ", u32_f32_max_obj.u32);print_float_binary("FLT_EPSILON ", u32_f32_epsilon_obj.u32);print_float_binary("FLT_MIN     ", u32_f32_min_obj.u32);print_float_binary("FLT_TRUE_MIN", u32_f32_true_min_obj.u32);print_float_binary("NaN         ", u32_f32_NaN_obj.u32);print_float_binary("INFINITY    ", u32_f32_inf_obj.u32);print_float_binary("-INFINITY   ", u32_f32_ne_inf_obj.u32);print_float_binary("zero(+0)    ", u32_f32_0_obj.u32);print_float_binary("zero(-0)    ", u32_f32_ne_0_obj.u32);//union u32f32 u32_f32_obj = { .u32 = 0xBCD3D6D8 };//0xBCD3D6D8 == -0.02585928142070770263671875printf("float obj_test     == 0x%08x, %.60f\n", u32_f32_obj.u32, u32_f32_obj.f32);print_float_binary("obj_test    ", u32_f32_obj.u32);//printf("float obj_test     == 0x%08x, sign(%s1) 2^exp(%d) fraction(%.30f)\n", u32_f32_obj.u32,u32_f32_obj.sign ? "-" : "+",((int)u32_f32_obj.exp) - 127,1.0 * u32_f32_obj.fraction / (1 << 23) + 1);printf("float obj_test     == 0x%08x, sign(%d) exp(%f) fraction(%.30f)\n", u32_f32_obj.u32,(-1) * (int)u32_f32_obj.sign,(pow(2, ((int)u32_f32_obj.exp) - 127)),(1.0 * u32_f32_obj.fraction / (1 << 23) + 1));printf("float obj_test     == 0x%08x, %.30f\n", u32_f32_obj.u32,(-1) * (int)u32_f32_obj.sign *(pow(2, ((int)u32_f32_obj.exp) - 127)) *(1.0 * u32_f32_obj.fraction / (1 << 23) + 1));return 0;
}int main(int argc, char** argv) {return test_float();
}
float FLT_MAX      == 0x7f7fffff, 340282346638528859811704183484516925440.000000
float FLT_EPSILON  == 0x34000000, 0.00000011920928955078125
float FLT_MIN      == 0x00800000, 0.000000000000000000000000000000000000011754943508222875079687365372222456778186655567720875215087517062784172594547271728515625
float FLT_TRUE_MIN == 0x00000001, 0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125
float NaN          == 0x7fc00000, nan
float INFINITY     == 0x7f800000, inf
float -INFINITY    == 0xff800000, -inf
float +0           == 0x00000000, 0.000000
float -0           == 0x80000000, -0.000000
float FLT_MAX      == 0x7f7fffff, binary(0111 1111 0111 1111 1111 1111 1111 1111)
float FLT_MAX      == 0x7f7fffff, sign(0)*(-1) 2^exp(1111 1110-127) fraction(1.111 1111 1111 1111 1111 1111)
float FLT_EPSILON  == 0x34000000, binary(0011 0100 0000 0000 0000 0000 0000 0000)
float FLT_EPSILON  == 0x34000000, sign(0)*(-1) 2^exp(0110 1000-127) fraction(1.000 0000 0000 0000 0000 0000)
float FLT_MIN      == 0x00800000, binary(0000 0000 1000 0000 0000 0000 0000 0000)
float FLT_MIN      == 0x00800000, sign(0)*(-1) 2^exp(0000 0001-127) fraction(1.000 0000 0000 0000 0000 0000)
float FLT_TRUE_MIN == 0x00000001, binary(0000 0000 0000 0000 0000 0000 0000 0001)
float FLT_TRUE_MIN == 0x00000001, sign(0)*(-1) 2^exp(0000 0000-127) fraction(1.000 0000 0000 0000 0000 0001)
float NaN          == 0x7fc00000, binary(0111 1111 1100 0000 0000 0000 0000 0000)
float NaN          == 0x7fc00000, sign(0)*(-1) 2^exp(1111 1111-127) fraction(1.100 0000 0000 0000 0000 0000)
float INFINITY     == 0x7f800000, binary(0111 1111 1000 0000 0000 0000 0000 0000)
float INFINITY     == 0x7f800000, sign(0)*(-1) 2^exp(1111 1111-127) fraction(1.000 0000 0000 0000 0000 0000)
float -INFINITY    == 0xff800000, binary(1111 1111 1000 0000 0000 0000 0000 0000)
float -INFINITY    == 0xff800000, sign(1)*(-1) 2^exp(1111 1111-127) fraction(1.000 0000 0000 0000 0000 0000)
float zero(+0)     == 0x00000000, binary(0000 0000 0000 0000 0000 0000 0000 0000)
float zero(+0)     == 0x00000000, sign(0)*(-1) 2^exp(0000 0000-127) fraction(1.000 0000 0000 0000 0000 0000)
float zero(-0)     == 0x80000000, binary(1000 0000 0000 0000 0000 0000 0000 0000)
float zero(-0)     == 0x80000000, sign(1)*(-1) 2^exp(0000 0000-127) fraction(1.000 0000 0000 0000 0000 0000)
float obj_test     == 0xbcd3d6d8, -0.025859281420707702636718750000000000000000000000000000000000
float obj_test     == 0xbcd3d6d8, binary(1011 1100 1101 0011 1101 0110 1101 1000)
float obj_test     == 0xbcd3d6d8, sign(1)*(-1) 2^exp(0111 1001-127) fraction(1.101 0011 1101 0110 1101 1000)
float obj_test     == 0xbcd3d6d8, sign(-1) 2^exp(-6) fraction(1.654994010925292968750000000000)
float obj_test     == 0xbcd3d6d8, sign(-1) exp(0.015625) fraction(1.654994010925292968750000000000)
float obj_test     == 0xbcd3d6d8, -0.025859281420707702636718750000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_997348.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

校招中的“熟悉linux操作系统”一般是指达到什么程度?

校招中的“熟悉linux操作系统”一般是指达到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&am…

官网:随便搞个?那不如不搞,搞不好就给公司减分了。

官网建设确实需要认真对待&#xff0c;不能随便搞。一个粗制滥造的官网可能会给公司带来负面影响&#xff0c;降低品牌形象和用户体验。以下是一些官网建设的重要原则&#xff1a; 专业性&#xff1a;官网应该展示公司的专业性和专业知识。它应该以专业的设计、内容和功能来展示…

uipath调用js代码

1&#xff0c;调用js代码&#xff0c;不带参数&#xff0c;没有返回值 为了去掉按钮的disabled属性 function(){ document.getElementsByClassName(submitBtn)[0].removeAttribute(disabled); } 2&#xff0c;调用js代码&#xff0c;带参数&#xff0c;没有返回值 输入参数&a…

Day 6.有名信号量(信号灯)、网络的相关概念和发端

有名信号量 1.创建&#xff1a; semget int semget(key_t key, int nsems, int semflg); 功能&#xff1a;创建一组信号量 参数&#xff1a;key&#xff1a;IPC对像的名字 nsems&#xff1a;信号量的数量 semflg&#xff1a;IPC_CREAT 返回值&#xff1a;成功返回信号量ID…

Hololens 2应用开发系列(2)——MRTK基础知识及配置文件配置(上)

Hololens 2应用开发系列&#xff08;2&#xff09;——MRTK基础知识及配置文件配置 一、前言二、MRTK基础知识2.1 MRTK概述2.2 MRTK运行逻辑2.3 MRTK配置文件介绍2.4 MRTK服务 三、配置文件使用3.1 总配置文件3.2 相机配置3.3 其他配置 参考文献 一、前言 在前面的文章中&…

有一点好看的wordpress外贸独立站模板

手机配件wordpress外贸网站模板 充电器、移动电源、手机膜、手机电池、手机壳、手机转接头等手机配件wordpress外贸网站模板。 https://www.jianzhanpress.com/?p3809 车载电器wordpress外贸网站模板 车载吸尘器、空气净化器、行车记录仪、车载充电器、车载影音导航等车载电…

两数之和(c++ 、c)

给定一个整数数组nums和一个整数目标值target&#xff0c;请你再该数组中找出和为目标值target的那两个数&#xff0c;并返回它们的数组下标 题目介绍方法一思路及算法复杂度分析 方法二&#xff1a;哈希表什么是哈希表思路及算法C中unordered_map用法复杂度分析 方法三&#x…

C++ STL自定义排序

更具体的看【速记】C STL自定义排序 - 知乎 (zhihu.com) sort sort第三个位置放的greater<int>和less<int>萌新可能会弄错&#xff0c;这两个单词不是更大和更小的意思&#xff0c;而是大于和小于&#xff0c;并且比较就是自定义排序中的前者和后者。 如果是less…

【CSP试题回顾】201503-3-节日

CSP-201503-3-节日 关键点&#xff1a;格式化输出 在C中&#xff0c;格式化输出通常利用iostream库中的功能&#xff0c;特别是iomanip头文件提供的一系列操作符。这些操作符用于控制输出格式&#xff0c;如宽度、填充、对齐方式等。在你提供的代码中&#xff0c;用于格式化输…

电脑要用多少V的电源?电脑电源输入电压是市电

台式电源的输出电压是多少&#xff1f; 电脑电源输出一般有三种不同的电压&#xff0c;分别是&#xff1a; 12V、5V、3.3V。 电脑电源负责给电脑配件供电&#xff0c;如CPU、主板、内存条、硬盘、显卡等&#xff0c;是电脑的重要组成部分。 工作电流根据不同的硬件及其使用状…

Linux 开发工具 yum、git、gdb

目录 一、yum 1、软件包 2、rzsz 3、注意事项 4、查看软件包 5、安装软件 6、卸载软件 二、git操作 1、克隆三板斧 2、第一次使用会出现以下情况&#xff1a; 未配置用户名和邮箱&#xff1a; push后弹出提示 三、gdb使用 1、背景 2、使用方法 例一&#xff1a…

根据标准化开发流程---解析LIN总线脉冲唤醒的测试方法和用例设计思路

前言&#xff1a;本文从标准化开发流程的角度&#xff0c;以LIN总线脉冲唤醒为切入点。从测试工程师的角度来讲测试工作应当如何展开&#xff08;结合我干测试总结出来的测试经验&#xff09;。希望大家都能从中有收获&#xff01;&#xff01;谢谢&#xff01;&#xff01; 1…

设计模式(十三)抽象工厂模式

请直接看原文:设计模式&#xff08;十三&#xff09;抽象工厂模式_抽象工厂模式告诉我们,要针对接口而不是实现进行设计。( )-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- …

Android 消息恢复 - 如何在 Android 上检索已删除的短信

最新调查显示&#xff0c;手机每天发送和接收的短信数以亿计&#xff0c;尤其是Android智能手机。但与此同时&#xff0c;Android消息丢失也每天都在发生。因此&#xff0c;如何恢复Android手机上已删除的短信对于那些在设备中保存了一些重要信息的人来说似乎非常重要。 在这里…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:PanGesture)

拖动手势事件&#xff0c;当滑动的最小距离超过设定的最小值时触发拖动手势事件。 说明&#xff1a; 从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 接口 PanGesture(value?: { fingers?: number; direction?: PanDir…

js--DOM树简介

DOM树将HTML文档以树状结构直管段表现出来&#xff0c;也称为节点树。 1、节点Node 节点是DOM树中的单个点&#xff0c;包括文档本身、元素、文本以及注释都属于是节点。 元素节点&#xff1a;所有的标签&#xff0c;html是根节点 属性节点&#xff1a;所有的属性 文本节点&…

基于springboot+vue的医疗挂号管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

1 数据分析概述与职业操守 (3%)

1、 EDIT数字化模型 E——exploration探索 &#xff08;是什么&#xff09; 业务运行探索&#xff1a;探索关注企业各项业务的运行状态、各项指标是否合规以及各项业务的具体数据情况等。 D——diagnosis 诊断 (为什么) 问题根源诊断&#xff1a;当业务指标偏离正常值时&…

Git保姆级使用教程

一、版本控制 1.1 团队开发问题 企业项目一般以团队形式实施开发&#xff0c;那团队开发中会出现哪些问题呢&#xff1f; 小明负责的模块就要完成了&#xff0c;就在即将Release之前的一瞬间&#xff0c;电脑突然蓝屏&#xff0c;硬盘光荣牺牲&#xff01;几个月来的努力付之…

学习统一的Hyper - network用于多模态MR图像合成和缺失模态的肿瘤分割

Learning Unified Hyper-Network for Multi-Modal MR Image Synthesis and Tumor Segmentation With Missing Modalities Learning Unified Hyper-Network for Multi-Modal MR Image Synthesis and Tumor Segmentation With Missing Modalities背景贡献实验方法多模态合成方法超…