64位浮点数_C语言常见面试题解析(1)——浮点数的比较

在一些C/C++语言的基础知识考查中,经常会遇到类似这样一个问题,给定两个浮点数,如何来判断它们是否相等?

今天就跟大家探讨一下这个问题,并通过程序试验结果来分析该问题的正确处理方法。

我们知道,在C语言中可以使用比较操作符(==)来比较两个数字是否相等,比如对于两个整数a和b,可以使用if(a==b)来判断,比如下面这段程序:

b4476f603d69f6119cda81f63ded5e88.png

整数比较

从程序以及运行结果我们可以清楚的看到,对于整数,比较操作符可以正确的给出比较结果。那么如果a和b变为浮点数,还可以这样使用吗?

让我们通过程序及其运行结果来分析,先看一下a和b相等的情况:

77b43dea45946b76b9248c79889bbe5e.png

浮点数相等的比较

通过运行结果可以看到当a、b相等时,比较操作符能得到正确的结果。

下面让我们再看一看a、b不相等,但是值很接近的情况,程序及运行结果如下:

7d5f09b02b01cd814521cbef41613f0b.png

浮点数很接近时会给出错误结果

在这个小程序中,因为c=a + b,而a、b又都不为0,所以从数学意义上来说,a和c并不相等,但是程序的运行结果却告诉我们a、b相等。为什么会这样呢?让我们将a、b的值以高精度方式输出,来看看有什么奥秘,请看下面程序及其运行结果:

b43e7d9e72383a837c88c9b8b9373aaf.png

高精度输出浮点数的值

可见,虽然a和c在数学上不相等,但是它们在计算机中的存储内存却相等,所以导致计算机在比较时做出了相等的结果。

为了进一步说明这个问题,让我们看看数字在计算机中的存储方式。我们知道计算机是以二进制方式来保存数据内容的,整数因为可以精确的转换为一个二进制数,所以可以准确的保存内容,但是小数却不能使用这样的方式。为了在计算机中保存小数,人们发明了浮点数,这种表示法是以适当的形式将比例因子表示在数据中,让小数点的位置根据需要而浮动,类似于数学中的科学计数法。这样,在位数有限的情况下,既扩大了数字的表示范围,又保持了有效精度。

浮点数主要由三部分组成,即符号、阶码与尾数,见下图是32位和64位浮点数的组成:

7f1ba4f5309dbde05a2ddc553ea1f253.png

浮点数的基本组成

浮点数的具体存储格式,以及如何将一个小数转换为二进制浮点数,可参考下面的标准。

  • 二进制浮点数算术标准(IEEE Std 754-1985),也称之为IEC 50599:1989,后来该标准被ISO收录,所以又称之为IOS/IEC/IEEE 60559:2011。
  • 与基数无关的浮点数算术标准(IEEE Std 854-1987)。

更多关于浮点数存储与运算的内容,已经超出了本文讨论的范围,感兴趣者可以参考相关标准的官方文档。

知道了浮点数存在精度的问题,所以上面的程序出现不正确的结果也就不足为奇了,那么回到本文开始时的问题,我们该如何来比较两个浮点数呢?只能使用近似相等,即根据程序的实际情况,定义一个精度值,当两个浮点数之差的绝对值小于该值时,即可认为它们相等,对于不等也可以使用类似的方法。

不过这里又引出一个问题,虽然用户可以定义一个精度值,那么如果为了提高精度,可以让该值无限小吗?显然也不可能,那么最小的精度是多少呢?其实为了方便浮点数的相关运算,标准库提供了一个float.h文件,并定义了一些辅助宏,比如用宏FLT_EPSILON表示单精度浮点数最高精度,以及表示双精度浮点数的宏DBL_EPSILON。

最后,给出一个规范的比较浮点数比较的函数。

402093f8b5239484d5d15b9a4f14250f.png

浮点数的正确比较方法

由于本人水平有限,文中如果有不足之处,欢迎大家指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值