浮点数运算——加减乘除都有哈

article/2025/9/9 21:49:03
  1. 什么是浮点数
  2. 浮点数运算异常

  3. IEEE 754 标准规定的五种异常情况

  4. 浮点数除0的问题

  5. 浮点数加减运算

  6. 浮点数乘除运算


导读:浮点数运算是一个非常有技术含量的话题,不太容易掌握。许多程序员都不清楚使用==操作符比较float/double类型的话到底出现什么问题。 许多人使用float/double进行货币计算时经常会犯错。

一、什么是浮点数?

在计算机系统的发展过程中,曾提出过多种方法表示实数

  【1】相对于浮点数的定点数(Fixed Point Number)。在这种表达方式中,小数点固定在实数所有数字中间的某个位置。货币的表达就可以使用这种方式,比如 99.00 或者 00.99 可以用于表达具有四位精度(Precision)小数点后有两位的货币值。由于小数点位置固定,所以可以直接用四位数值来表达相应的数值。

  【2】有理数表达方式,即用两个整数的比值来表达实数。定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固定位数的整数部分和小数部分,不利于同时表达特别大的数或者特别小的数。最终,绝大多数现代的计算机系统采纳了所谓的浮点数表示法。

  【3】浮点数表达方式, 这种表达方式利用科学计数法来表达实数,即用一个尾数(Mantissa ),一个基数(Base),一个指数(Exponent)以及一个表示正负的符号来表达实数。比如 123.45 用十进制科学计数法可以表达为 1.2345  * 10^2 ,其中 1.2345 为尾数,10 为基数,2 为指数。浮点数利用指数达到了浮动小数点的效果,从而可以灵活地表达更大范围的实数。尾数有时也称为有效数字(Significand)。尾数实际上是有效数字的非正式说法。

依据IEEE(电气和电子工程协会)754 标准 存储浮点数   👉【上一篇文章中有介绍此标准】

二、浮点数运算异常

上述运算结果可能出现以下几种情况: 

阶码上溢一个正指数超过了最大允许值+∞/-∞/溢出
阶码下溢一个负指数超过了最小允许值+0/-0
尾数溢出
(尾数溢出,结果不一定溢出)
最高有效位有进位右规
非规格化尾数数值部分高位为0
右规或对阶时,右段有效位丢失
左规
尾数舍入

三、 IEEE 754 标准规定的五种异常情况

  👉【上一篇文章中有介绍此标准】

无效运算(无意义)
 运算时有一个数是非有限数,如: 加/ 减∞、0 x ∞、∞/∞
 结果无效,如: 源操作数是NaN、0/0、x REM 0、∞REMy 
除以0(即:无穷大)
数太大(阶上溢): 对于SP,指阶码E >1111 1110(指数大于127)
数太小(阶下溢): 对于SP,指阶码E < 0000 0001(指数小于-126)
结果不精确(舍入时引起),例如1/3、1/10等不能精确表示成浮点数

上述情况硬件可以捕捉到,因此这些异常可设定让硬件处理,也可设定让软件处理。让硬件处理时,称为硬件陷阱

 四、浮点数除0的问题

#include <stdio.h>
#include <conio.h>
#include <windows.h>int mian()
{int a = 1, b = 0;printf("Divisionby zero:%d\n", a / b);return 0;
}
//程序编译报错 

结果 👇

#include <stdio.h>
#include <conio.h>
#include <windows.h>int main(void)
{double x = 1, y = -1.0, z = 0.0;printf("Division by zero : % f      % f\n",x/z,y/z);system("pause");return 0;
}
//浮点数运算中,一个有限数除以0, 结果为正无穷大(负无穷大)

 结果 👇

五、浮点数加减运算

使用补码表示阶码和尾数的浮点数的加减运算

运算步骤如下:

1.对阶:对阶的原则是小的阶码向大的阶码看齐,这是因为小阶码增大数值时,尾数部分右移舍去的是尾数的低位部分,但如果让大阶码向小的阶码看齐,则尾数部分相应左移,将会丟失尾数的高位部分,导致运算结果的精确度大大降低。

对阶又包括如下两个步骤:

  1. 求阶差:通过对两个阶码进行减法运算实现,这不仅能知道阶码的大小,还能求出两个阶码的具体差值。

  2. 阶码的调整与尾数的移位,可按下面方式进行:

         若 m > n,则将浮点数 y 的尾数右移 m - n 位。

         若 m < n,则将浮点数 x 的尾数右移 n - m 位。

2.尾数运算:对阶完成后可按照定点数的加减运算法则执行尾数加减操作,注意,对于阶码小的那个浮点数,应该使用对阶后的尾数参加运算。

3.结果规格化:结果规格化就是使运算结果成为规格化数,为了运算处理方便,可让尾数的符号位扩展为两位,当尾数运算结果不是 11.0XX…X 或 00.1XX…X 的形式时,则应进行相应的规格化处理:

  1. 当尾数双符号位为 01 或 10 时,需要向右规格化,且只需将尾数右移一位,同时将结果的阶码值加 1。
  2. 当尾数运算结果为 11.1XX…X 或 00.0XX…X 时需要左移规格化,而且左移次数不固定,与运算结果的形式有关。左规的方法是尾数连同符号位一起左移位,结果的阶码减 1,直到尾数部分出现 11.0 或 00.1 的形式为止。

4.舍入:在对阶右移和右移规格化操作时,尾数末尾的几位会超出机器字长而被丢掉,从而产生误差。这时,计算机可以按选定的方式进行舍入操作,常用的舍入方法如下:

  1. 末位恒置1法:只要因移位而丢失的位中有一位是1,就把运算结果的最低位置1,而不管最低位原来是0还是1。
  2. 0舍1入法:当丢失位数的最高位是1时将尾数的末尾加1。

5.溢出判断:由于浮点数中阶码的位数决定数的表示范围,因此对于浮点运算而言,当阶码出现溢出时才表示运算结果溢出,即当阶码的符号位为 01 和 10 时表示运算结果溢出。

六、浮点数乘除运算

浮点数乘除运算在正式运算前会对操作数进行预处理。对于乘法如果有一个操作数为0则结果为0。对于浮点数除法,若被除数为0,则结果为0。除数为0分两种情况,第一种是被除数非零,第二种是被除数为0。下面介绍一下两种除数为0:

  • 除数为0,被除数不为0: 结果为无穷大。在IEEE 754标准下就是阶码全为1,尾数全为0。
int main(void)
{float a = 1.0 ;float b = 0 ;float c; c = a / b ;           // 1.0 / 0 printf("%f", c);      //1.#INF00return 0;
}
  • 除数被除数都为0:结果是NAN(not a number)。在IEEE 754标准下阶码全为1,尾数非0。
int main(void)
{float a = 0.0 ;float b = 0.0 ;float c; c = a / b ;           // 0.0 / 0.0 printf("%f", c);      // -1.#IND00return 0;
}

 注:在Windows系统下,-1.#IND00即代表nan,Linux系统下会输出nan。

运算规则:两个浮点数相乘,乘积的阶码应为相乘两数的阶码之和,乘积的尾数应为相乘两数的尾数之积。两个浮点数相除,商的阶码为被除数的阶码减去除数的阶码,尾数为被除数的尾数除以除数的尾数所得的商,下面用数学公式来描述。

运算步骤
1、 0操作数检查
对于乘法:检测两个尾数中是否一个为0,若有一个为0,则乘积必为0,不再做其他操作;若两尾数均不为0,则可进行乘法运算。
对于除法:若被除数x为0,则商为0;若除数y为0,则商为∞,另作处理。若两尾数均不为0,则可进行除法运算。
2、阶码加减操作
在浮点乘除法中,对阶码的运算只有4种,即+1、 -1两阶码求和以及两阶码求差。当然,在运算的过程中,还要检查是否有溢出,因为两个同号的阶码相加或异号的阶码相减可能产生溢出。
3、尾数乘/除操作
按照定点小数的阵列乘除法运算方法对两个浮点数的尾数进行乘除运算。为了保证尾数相除时商的正确性,必须保证被除数尾数的绝对值一定小于除数尾数的绝对值。若被除数尾数的绝对值大于除数尾数的绝对值,需对被除数进行调整,即被除数的尾数每右移1位,阶码加1,直到被除数尾数的绝对值小于除数尾数的绝对值。
4、结果规格化及舍入处理
可直接采用浮点数加减法的规格化和舍入处理方式。主要有以下两种:

  • 无条件地丢掉正常尾数最低位之后的全部数值。这种办法被称为截断处理,其好处是处理简单,缺点是影响结果的精度。
  • 运算过程中保留右移中移出的若千高位的值,最后再按某种规则用这些位上的值进行修正尾数。这种处理方法被称为舍入处理

当尾数用原码表示时,舍入规则比较简单。最简便的方法是,只要尾数的最低位为1,或移出的几位中有为1的数值,就使最低位的值为1。另一种是0舍1入法,即当丢失的最高位的值为1时,把这个1加到最低数值位上进行修正。
当尾数用补码表示时,所用的舍入规则应该与用原码表示时产生相同的处理效果。
具体规则是:

  • 当丢失的各位均为0时,不必舍入。
  • 当丢失的各位数中的最高位为0,且以下各位不全为0时,或者丢失的最高位为1,以下各位均为0时,舍去丢失位上的值。
  • 当丢失的最高位为1,以下各位不全为0时,执行在尾数最低位加1的修正操作。
     

例题 👇


 


  Thank you ^_^ 


http://chatgpt.dhexx.cn/article/XigYi8iP.shtml

相关文章

浮点数的运算步骤

浮点数的运算步骤 浮点数的加减运算一般由以下五个步骤完成&#xff1a;对阶、尾数运算、规格化、舍入处理、溢出判断 一、对阶 所谓对阶是指将两个进行运算的浮点数的阶码对齐的操作。对阶的目的是为使两个浮点数的尾数能够进行加减运算。因为&#xff0c;当进行M x2Ex与M …

浮点数运算

今天学习了浮点数运算&#xff08;加减乘除&#xff09;。浮点数运算主要包括两部分&#xff1a;指数运算和尾数运算。在IEEE754标准下&#xff0c;指数运算就是阶码的运算&#xff0c;类似于无符号数运算。尾数运算是原码运算。之前一直很疑惑为什么前面的教材在介绍原码运算&…

计算机组成原理:浮点数的加、减、乘、除运算(含实例完整运算)

目录 浮点数的加减运算 零操作数的判断 对阶操作 尾数的加减操作 尾数的规格化 结果的舍入处理 结果的溢出判断 加减实例运算过程 浮点数的乘除法 零操作数的检查 阶码的加减操作 尾数的乘除操作 结果的规格化、舍入处理及溢出的判断 具体的操作如下图 乘除实例运算…

浮点数的运算方法

浮点数的运算方法 一、浮点数的表示1.浮点数的表示2.IEEE 754标准3.浮点数类型 二、浮点数的加减法1.定义2.运算步骤 三、运算部件四、强化练习 一、浮点数的表示 1.浮点数的表示 Ms表示尾数的符号位&#xff0c;E中1bit保存阶码的符号位其余空间存放阶码值&#xff0c;M中存放…

typeScript 接口(interface)及其与类型别名(type)的区别

背景 最近自己在学习一些视频剪辑相关的工具&#xff0c;像爱剪辑&#xff0c;剪映这些软件。然后就想自己是不是也可以实现一个类似的&#xff0c;轻量级的在线剪辑工具。最后发现这个款node端的工具库FFCreator&#xff0c;接下来简单介绍一下如何来搭建开发环境&#xff0c…

Type Description : This type is a general type that can be used to declare

错误描述&#xff1a; Complex type: param-valueType Description : This type is a general type that can be used to declare parameter/value lists. 解决方法&#xff1a; 把0移到init-param下面

Type and Value

Type and Value 前言一、reflect.Type1.1 数据结构1.2 方法1.2.1 所有类型通用方法1.2.2 不同基础类型的专有方法 二、reflect.Value总结参考资料 前言 reflect.Type和reflect.Value是go 反射的两大基本类型&#xff0c;一个管变量的类型方面&#xff0c;一个管变量的值方面。…

typescript interface 与 type 声明类型的区别

在 typescript 中, 我们定义类型有两种方式&#xff1a; 接口(interface) 和类型别名(type alias) 在官方文档中我们可以看到: Unlike an interface declaration, which always introduces a named object type, a type alias declaration can introduce a name for any kind…

type是什么

作者&#xff1a;newis 链接&#xff1a;https://www.zhihu.com/question/376890141/answer/1302417252 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 程语言的Type的话&#xff0c;有在不同的场景下有不同的意义…

Type-C

一、Type-C 从USB TYPE-C 的Spec上截一个USB TYPE-C母座的pin脚图&#xff1a; 可以看出&#xff0c;母座上有24根信号&#xff0c; 其中电源和地占据了8根&#xff0c;用于提升电流传输能力&#xff0c;剩下16个&#xff1a; &#xff08;1&#xff09;传输USB3数据的RXx和…

Java Type

Type 是Java 编程语言中所有类型的公共高级接口&#xff08;官方解释&#xff09;&#xff0c;也就是Java 中所有类型的”爹“。其中”所有类型“的描述尤为指的关注。它并不是我们平常工作中经常使用的int、String、List、Map等数据类型&#xff0c;而是从Java语言角度磊说&am…

常见USB接口总结:Type-A、Mini-USB、Micro-USB、Type-C等等

写在前面 最近在整理之前的笔记&#xff0c;打算把一些有价值的笔记发到CSDN分享一下。这篇总结参考的链接如下&#xff0c;结合了自己找的一些图片&#xff0c;非原创&#xff0c;侵权的话私聊我删除。 参考文章链接 https://mb.zol.com.cn/514/5147157.html 总览 标准Type-…

# USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义

USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义 文章目录 USB Type-A、Type-B、Type-C及MicroUSB、MiniUSB接口定义1 USB Type-A&#xff08;USB-A&#xff09;2 USB Type-B&#xff08;USB-B&#xff09;3 USB Type-C&#xff08;USB-C&#xff09;3.1 24Pin3.2 16Pi…

Java FileReader相对路径

实验一快要到DDL了&#xff0c;今天在用Javac和Java命令手动执行实验一的代码的时候发现一个问题&#xff0c;当时在IDEA中运行正常的代码&#xff0c;在javac编译手动用java执行的时候发现并不能通过&#xff0c;出问题的代码是一段&#xff08;试图&#xff09;使用相对路径来…

详解HTML的相对路径写法,详解URL相对路径的写法

虽然现在搭网站都会用各种框架&#xff0c;路径方面使用相对路径可能已经比较少了&#xff0c;不过还是总结一下吧。 假设D盘这个路径下有一些文件&#xff1a; D:\例子\html\images\ D:\例子\html\style\ D:\例子\html\example.html D:\例子\html\tupian.gif 1.若引用的资源和…

Python读取相对路径文件

例如下图目录结构: 第一种情况: 1)xxx.py想要打开a.txt,使用相对路径,有如下两种方式: 思路: xxx.py想打开的是b_file下的文件,XXX.py和b_file都在文件目录之下,两者是同级目录,因此操作就是在当前目录向下搜索,因此就可以很容易理解下面的意思了 特别提示:… \是错…

html 的相对路径和绝对路径

整篇文章是以 src 标签进行演示。 文章目录 一、相对路径 1、同级目录查找 2、上一级目录查找 3、下一级目录查找 二、绝对路径 一、相对路径 &#x1f475;相对路径&#xff1a;从当前所处的目录开始查找。 1、同级目录查找 写法&#xff1a; 1.1.直接写文件名&#xf…

java web项目 相对路径怎么写_理解JavaWeb项目中的路径问题——相对路径与绝对路径...

背景:html 在刚开始学习javaweb,使用servlet和jsp开发web项目的过程当中,一直有一个问题困扰着我:servlet 和 jsp 之间相互跳转,跳转的路径应该如何书写,才能正确的访问到相应的servlet或jsp文件?后来,在课堂上,通过老师的讲解,再加上本身的一些思考和实验,终于对we…

相对路径 各种情况

1.相对路径概念 1.1 相对路径就是相对于目标文件或&#xff08;相对虚拟目录&#xff09;的位置。&#xff0c;请看上图&#xff0c;“a.html” 文件里引用了“b.jpg”图片&#xff0c;由于“b.jpg”图片相对于“a.html”来说&#xff0c;是在同一个目录的,那么要在“a.html”文…

java中相对路径怎么写_java中如何使用相对路径读取文件

java中使用相对路径读取文件的方法:1、使用文件【File file = new File(“src/test.txt”)】方法;2、使用类的相对路径;3、使用当前线程的类加载器;4、读取web工程下的文件。 【相关学习推荐: java中使用相对路径读取文件的方法: 一、简单粗暴的 File file = new File(“…