news 2026/7/14 20:25:36

数值计算: IEEE754浮点数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数值计算: IEEE754浮点数

文章目录

  • IEEE754浮点数
      • 单精度(float,32bits)
      • 双精度(double,64bits)
      • 浮点数加减法流程逻辑
        • 工具程序

IEEE754浮点数

What Every Computer Scientist Should Know About Floating-Point Arithmetic

一个浮点数包括三部分: 符号部分(Sign)、指数部分(Exponent)、分数部分(Fraction)

  • IEEE754浮点数不是均匀分布的。仅能代表有限个数的实数。数轴上有空隙,多数浮点数是不能被精确表示的,比如是十进制数0.1就不能被IEEE754浮点数精确表示
  • 对于normal浮点数,1.xxxx中的1是隐含存在的
  • normal浮点数0有正负之分(S=0/1, E=0, Fraction=0). 函数atan2(y,x)按IEEE-754标准x取正0和负0,结果对应π \piπ− π -\piπ(Intel Fortran和Matlab中的atan2函数对正负零的处理有不同之处)
  • 有subnormal数(非常小,接近数值0): E=0, Fraction部分不为0
  • IEEE754浮点数内部计算寄存器多出两位(保证gaurd & rounding)(guard bits是三位?)
  • 有四种截断/舍入模式(rounding)
  • 有overflow/underflow浮点计算异常。underflow危害不大,overflow需要特殊关注。overflow一个情形是从其他类型转换引起的(e.g.,一个很大的整数转成float, 或double转成float), 另外一个教科书级例子是hypot计算x 2 + y 2 \sqrt{x^2+y^2}x2+y2, 和求多维向量长度∑ x i 2 \sqrt{\sum{x_i^2}}xi2, 类似计算要时刻避免浮点overflow溢出!
  • 比较: inf>1, 返回1; NaN>1、NaN==1、NaN<1都返回0
  • 对于subnormal数一般有两种处理方式: flush to zero .vs. gradual underflow。subnormal数对性能影响较大,可以指定编译选项打开或关闭flush to zero;gradual underflow一般对比较精细计算中有帮助,比如求函数数值导数等。

单精度浮点数可表示范围:


单精度(float,32bits)

说明
Bias127
E范围[1…254], 0和255保留
Range2 − 126 2^{-126}2126to2 + 127 2^{+127}2+127

一些特殊单精度数(调用std::numeric_limits<float>获取)

浮点数二进制表示
000000000000000000000000000000000
-010000000000000000000000000000000
100111111100000000000000000000000
-110111111100000000000000000000000
eps00110100000000000000000000000000
1+eps00111111100000000000000000000001
min00000000100000000000000000000000
max01111111011111111111111111111111
denorm_min00000000000000000000000000000001
infinity01111111100000000000000000000000
sNaN01111111101000000000000000000000
qNaN01111111110000000000000000000000

双精度(double,64bits)

说明
Bias1023
E范围[1…2046], 0和2047保留
Range2 − 1022 2^{-1022}21022to2 + 1023 2^{+1023}2+1023

一些特殊双精度数(调用std::numeric_limits<double>获取)

浮点数二进制表示
00000000000000000000000000000000000000000000000000000000000000000
-01000000000000000000000000000000000000000000000000000000000000000
10011111111110000000000000000000000000000000000000000000000000000
-11011111111110000000000000000000000000000000000000000000000000000
eps0011110010110000000000000000000000000000000000000000000000000000
1+eps0011111111110000000000000000000000000000000000000000000000000001
min0000000000010000000000000000000000000000000000000000000000000000
max0111111111101111111111111111111111111111111111111111111111111111
infinity0111111111110000000000000000000000000000000000000000000000000000
sNaN0111111111110100000000000000000000000000000000000000000000000000
qNaN0111111111111000000000000000000000000000000000000000000000000000

浮点数加减法流程逻辑

工具程序
/************************************ 测试IEEE浮点数标准、表示形式等 *************************************/#include<cmath>#include<iostream>#include<bitset>#include<limits>#include<type_traits>#include<cstdint>#include<sstream>#include<string>using namespace std;template<typename R>std::ostream&dump_bits(constR x,std::ostream&os=std::cout){uint8_t*u8=(uint8_t*)&x;strings("");//assume little-endianfor(inti=sizeof(R)-1;i>=0;--i){std::bitset<8>b(u8[i]);s+=b.to_string();}os<<s;returnos;}template<typename R>std::ostream&dump_hex(constR x,std::ostream&os=std::cout){os<<std::hexfloat;os<<x;os<<std::defaultfloat;returnos;}template<typename T>voidprint_limits(){using flimits=numeric_limits<T>;cout<<"radix:\t"<<flimits::radix<<"\n";cout<<"min_exponent:\t"<<flimits::min_exponent<<"\n";cout<<"max_exponent:\t"<<flimits::max_exponent<<"\n";cout<<"digits:\t"<<flimits::digits<<"\n";cout<<"digits10:\t"<<flimits::digits10<<"\n";cout<<"epsilon:\t"<<flimits::epsilon()<<"\n";cout<<"inf:\t"<<flimits::infinity()<<"\n";cout<<"qNan:\t"<<flimits::quiet_NaN()<<"\n";cout<<"sNan:\t"<<flimits::signaling_NaN()<<"\n";cout<<"min:\t"<<flimits::min()<<"\n";cout<<"max:\t"<<flimits::max()<<"\n";}template<typename T>voidprint_bits_and_hex(){static_assert(std::is_same_v<T,float>||std::is_same_v<T,double>||std::is_same_v<T,longdouble>);using flimits=numeric_limits<T>;autodump=[](std::ostream&os,string name,constT&x)->std::ostream&{os<<name<<"\t";dump_bits(x,os);os<<" ";os<<std::hexfloat;os<<x;os<<std::defaultfloat;os<<"\n";returnos;};dump(cout,"infinity",flimits::infinity());dump(cout,"sNaN",flimits::signaling_NaN());dump(cout,"qNaN",flimits::quiet_NaN());dump(cout,"0",T(0.0));dump(cout,"-0",T(-0.0));dump(cout,"1",T(1));dump(cout,"-1",T(-1));dump(cout,"eps",flimits::epsilon());dump(cout,"1+eps",flimits::epsilon()+T(1));dump(cout,"min",flimits::min());dump(cout,"max",flimits::max());dump(cout,"denorm_min",flimits::denorm_min());}intmain(intargc,char**argv){cout<<R"(=========================================================================单精度浮点数(float)limits=========================================================================)"<<"\n";print_limits<float>();cout<<R"(=========================================================================双精度浮点数(double)limits=========================================================================)"<<"\n";print_limits<double>();cout<<R"(=========================================================================单精度浮点数(float)二进制模式=========================================================================)"<<"\n";print_bits_and_hex<float>();cout<<R"(==========================================================================双精度浮点数(double)二进制模式==========================================================================)"<<"\n";print_bits_and_hex<double>();cout<<R"(==========================================================================长精度浮点数(longdouble)二进制模式==========================================================================)"<<"\n";print_bits_and_hex<longdouble>();//=======================================================================//inf可和其他结果比较cout<<((numeric_limits<float>::infinity()>1.0f)?"inf>1":"inf<=1")<<"\n";//inf参加运算,结果是infcout<<numeric_limits<float>::infinity()/2.0f<<"\n";//nan和其他数值比较,结果都为falsecout<<(numeric_limits<float>::quiet_NaN()>1.0f)<<"\n";cout<<(numeric_limits<float>::quiet_NaN()<1.0f)<<"\n";//0有特殊运算定义cout<<(-0.0f<0.0f)<<"\n";return(0);}//编译: g++ -std=c++17 cxx_ex3.cpp
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 9:50:09

Markdown写文档更方便:记录lora-scripts训练实验日志

lora-scripts 训练实践&#xff1a;用 Markdown 管理 LoRA 实验日志 在 AIGC 浪潮席卷各行各业的今天&#xff0c;越来越多开发者和创意工作者希望拥有“属于自己的 AI 模型”——无论是复刻个人画风、打造品牌视觉 IP&#xff0c;还是让大模型掌握特定领域的专业知识。但现实是…

作者头像 李华
网站建设 2026/7/7 20:59:33

又拍云是否支持lora-scripts资源分发?合作可能性探讨

又拍云是否支持lora-scripts资源分发&#xff1f;合作可能性探讨 在生成式AI迅速“破圈”的今天&#xff0c;越来越多的个人创作者和小型团队开始尝试训练专属的LoRA模型——无论是打造独特的艺术风格&#xff0c;还是为垂直行业定制语言能力。而随着这类轻量化微调需求的增长&…

作者头像 李华
网站建设 2026/6/26 9:50:09

Quarkus 2.0物联网集成实战(从设备接入到云原生部署大揭秘)

第一章&#xff1a;Quarkus 2.0物联网集成概述Quarkus 2.0 作为一款专为云原生和 GraalVM 优化的 Java 框架&#xff0c;显著提升了在资源受限环境中运行微服务的能力&#xff0c;尤其适用于物联网&#xff08;IoT&#xff09;场景下的边缘计算与设备协同。其快速启动时间和低内…

作者头像 李华
网站建设 2026/7/4 3:21:12

企业微信集成lora-scripts审批流程自动化

企业微信集成lora-scripts审批流程自动化 在企业日常运营中&#xff0c;审批流程往往伴随着大量重复性、规则明确但又依赖人工判断的任务&#xff1a;市场部提交的设计稿是否符合品牌视觉规范&#xff1f;法务收到的合同里有没有遗漏关键条款&#xff1f;客服回复客户时语气是否…

作者头像 李华
网站建设 2026/7/12 14:02:10

x64架构下的Java向量化革命:5步实现代码性能跃迁

第一章&#xff1a;x64架构下的Java向量化革命&#xff1a;5步实现代码性能跃迁现代x64处理器支持SIMD&#xff08;单指令多数据&#xff09;指令集&#xff0c;Java通过HotSpot JVM的自动向量化机制&#xff0c;能够将合适的循环计算转换为使用AVX、SSE等指令&#xff0c;显著…

作者头像 李华