当前位置: 首页 > news >正文

为什么浮点数会搞出Infinity和NAN两种类型?浮点数的底层原理?IEEE 754标准揭秘?

目录

什么是NAN?

不同编程语言的NaN

为什么浮点数会搞出Infinity和NAN两种类型?

浮点数

小数点位置浮动的原因

浮点数和整数

浮点数指令

精确性

浮点数的类型

为什么叫浮点数?

小数点位置浮动的原因

IEEE 754起源于intel公司

IEEE 754标准

编程语言的浮点数都使用IEEE754吗?

浮点数指令

浮点数的精确性差?

浮点数操作丢失精度


什么是NAN?

NAN全称是Not a Number,常在浮点数运算中使用,首次引入NaN的是1985年的IEEE 754浮点数标准。如除以零、求负数的平方根等错误的操作,会返回NAN. 例如可以求一个负数的平方根,结果用isnan函数(来自math.h)返回真。

不同编程语言的NaN

  • JS全局函数isNaN和ES6引入的Number.isNaN函数存在差异,后者更符合字面理解。
    Number.isNaN(undefined)返回false,而全局isNaN(undefined)返回true.

为什么浮点数会搞出Infinity和NAN两种类型?

本质上,Infinity和NAN内部存储依然是一个浮点数,只是需要和正常的浮点数区分开。IEEE754标准规定浮点数有指数E和尾数M部分,标准规定当E等于255(E的最大值),可代表Infinity无穷和NAN非数两种。

  • E == 255,M == 0:Infinity
  • E == 255,M != 0: NAN

这意味着,其它任何有效的浮点数指数E都不会是255.

浮点数

浮点数相比定点数或者整数,为了处理小数点引入了指数,导致小数点的位置根据不同浮点数而不同,故名为Floating Point Number. 一般而言,IEEE754标准被大部分编程语言的浮点数使用,它节省了浮点数的保存空间。如不然,浮点数可能按每一位ASCII码保存,包括整数部分、小数点和小数部分,占用空间不可控制。

小数点位置浮动的原因

浮点数整数部分长度不一,为了统一整数部分和指数部分,把所有整数都转换成0.xx格式,造成小数点位置不一。

浮点数和整数

  • 浮点数的位级存储和整数完全不同,整数1和浮点数1.0存储也截然不同。通过调试器查看int变量和float变量的内存存储,或者写一段dump字节代码比较其区别,还有一种方式,C/C++ %a格式串可用十六进制形式表达浮点数(其他编程语言可能不适用)。
  • 不同浮点数位级存储也不相同,float和double是不同的。
  • 浮点数和整数运算,整数会默认先转换成浮点数。
    f = f + i;
    cvtsi2ss xmm0,dword ptr [i]
    addss xmm0,dword ptr [f]
    movss dword ptr [f],xmm0

浮点数指令

早期计算机根本没有浮点数处理ALU,浮点数靠软件整数去模拟,性能极低。后来,加入了浮点数FPU,浮点数处理速度极大提升,比如xmm寄存器。

  • double f = 2.25; // IEEE 754内存存储
  • 00501056 movsd xmm0,mmword ptr [__real@4002000000000000 (0502108h)]

精确性

浮点数的表达方式利用整数位和小数位计算的2n数值(n可正可负)计算,必然出现不准确。1.5可精确表示,0.3却无法精确表示。有的书籍上提到,浮点数不要用==或!=判断,其实是考虑有不精确表达的可能。在商业银行金融领域,这是不能容忍的。市面上,只要是用IEEE 754标准表达的浮点数,运算一定是不精确的。

  • COBOL编程语言是上古时期可以处理小数精确度很好的一门语言,因为它真的用模拟的形式保存小数点和小数位,而非IEEE 754这种压缩版。
  • C#引入了decimal类型处理小数点更精确。如下两种不同类型变量输出的结果第一个会更精确。
    decimal d = 3.14159265124m;
    float f = 3.14159265123f;

浮点数的类型

尽管4字节的浮点数可表达相当大的数值,但对于人类而言,总不够用。一般而言,浮点数有3种类型,单精度的float和双精度的double以及更长的long double, 可参考:数据类型大小

  • C语言为了区分float和double, 输入时用%f代表float, %lf代表double, 但对于输出%f和%lf作用相同。
  • C语言中float类型是默认转换成double去处理,如下图所示。
  • C99引入了long double (%Lf), 注意并不意味long double一定比double要长,根据编译器选择。

为什么叫浮点数?

浮点数相比定点数或者整数,为了处理小数点引入了指数,导致小数点的位置根据不同浮点数而不同,故名为Floating Point Number. 一般而言,IEEE754标准被大部分编程语言的浮点数使用,它节省了浮点数的保存空间。如不然,浮点数可能按每一位ASCII码保存,包括整数部分、小数点和小数部分,占用空间不可控制。

小数点位置浮动的原因

浮点数整数部分长度不一,为了统一整数部分和指数部分,把所有整数都转换成0.xx格式,造成小数点位置不一。

浮点数和整数有什么不同?

IEEE 754起源于intel公司

1980年,intel公司发布8087浮点数协处理器,它对浮点数的设计还算不错,被IEEE采纳为标准。它设计了3块,符号位、指数域和分数值。本质上是在较小的空间,如4字节或8字节,分成不同位域,存储更多数值的讯息,避免用一个字节表示十进制浮点数一位,造成空间浪费。

IEEE 754标准

IEEE 754是IEEE二进制浮点数算术标准(IEEE Standard for Floating-Point Arithmetic)的简称,于1985年首次发布,并在后续的1987年、2008年和2019年进行了修订。这是由国际电气和电子工程师协会(Institute of Electrical and Electronics Engineers,IEEE)制定的一种浮点数运算标准,也是20世纪80年代以来最广泛使用的浮点数运算标准,被许多CPU与浮点运算器所采用。大部分编程语言都采用IEEE 754标准作为浮点数标准,C语言诞生比它还早,后面也是采用此标准。

IEEE 754起源于intel公司

编程语言的浮点数都使用IEEE754吗?

对于主流的一些编程语言,例如C、Objective-C、C++、Swift、C#、Java和JavaScript都按照IEEE754标准实作浮点数。

浮点数指令

早期计算机根本没有浮点数处理ALU,浮点数靠软件整数去模拟,性能极低。后来,加入了浮点数FPU,浮点数处理速度极大提升,比如xmm寄存器。最早有FPU功能是intel的8087处理器。

  • double f = 2.25; // IEEE 754内存存储
  • 00501056 movsd xmm0,mmword ptr [__real@4002000000000000 (0502108h)]

浮点数的精确性差?

浮点数的表达方式利用整数位和小数位计算的2n数值(n可正可负)计算,必然出现不准确。1.5可精确表示,0.3却无法精确表示。有的书籍上提到,浮点数不要用==或!=判断,其实是考虑有不精确表达的可能。在商业银行金融领域,这是不能容忍的。

  • COBOL编程语言是上古时期可以处理小数精确度很好的一门语言,因为它真的用模拟的形式保存小数点和小数位,而非IEEE 754这种压缩版。
  • C#引入了decimal类型处理小数点更精确。如下两种不同类型变量输出的结果第一个会更精确。
    decimal d = 3.14159265124m;
    float f = 3.14159265123f;

浮点数操作丢失精度

  • C# 提供了round-trip格式符R或者r可以确保浮点数在运算过程中没有丢失精度。
    例如 string s = string.Format("{0:R}", float_val), 字符串s在后面被重新解析成浮点数不会改变。

浮点数指令 不同的浮点数类型 计算机存储单元bit


若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!

微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

相关文章:

  • VSCode安装与环境配置(Mac环境)
  • 【计算机视觉】CV实战项目- Face-and-Emotion-Recognition 人脸情绪识别
  • sqlilabs-Less11 POST注入
  • 一个项目中多个Composer的使用方法
  • LibModbus 主从机通信应用实例
  • 【今日三题】判断是不是平衡二叉树(递归) / 最大子矩阵(二维前缀和) / 小葱的01串(滑动窗口)
  • 【技术派后端篇】 Redis 实现用户活跃度排行榜
  • 数据库备份-docker配置主从数据库
  • IntelliJ IDEA右键快捷方式设置方法
  • Sentinel源码—5.FlowSlot借鉴Guava的限流算法二
  • uniApp小程序保存定制二维码到本地(V3)
  • YOLOv11改进有效涨点专栏:从理论到实战的深度优化指南
  • docker转移镜像
  • 那就聊一聊mysql的锁
  • 【基于Fluent+Python耦合的热管理数字孪生系统开发:新能源产品开发的硬核技术实践】
  • CMFA在自动驾驶中的应用案例
  • 国产的 Java Solon v3.2.0 发布(央企信创的优选)
  • Go-zero框架修改模版进行handler统一响应封装
  • Python基于知识图谱的医疗问答系统【附源码、文档说明】
  • A股周度复盘与下周策略 的deepseek提示词模板
  • 体坛联播|巴萨三球逆转塞尔塔,CBA季后赛山西横扫广东
  • 儿童阅读空间、残疾人友好书店……上海黄浦如何打造城市书房
  • 海口市美兰区委副书记、区长吴升娇去世,终年41岁
  • 《王牌对王牌》确认回归,“奔跑吧”将有主题乐园
  • 地铁口被吐槽像棺材?杭州地铁公司回应:是一个标志性出入口
  • 圆桌|并购重组迎政策红利期,并购基金如何把握发展机遇?