【C/C++】 浮点数的存储结构以及与之相关的存储误差观察

这32个比特以类似于科学计数法的形式来表达一个浮点数,按照IEEE 754标准,其数学表示为:如图2-6所示,最高的1位用做符号位,接着的 8

浮点数就是所谓的小数,一个float类型的对象占据4个字节共32比特。这32个比特以类似于科学计数法的形式来表达一个浮点数,按照IEEE 754标准,其数学表示为:

【C/C++】 浮点数的存储结构以及与之相关的存储误差观察

知识产权协议

允许以教育/培训为目的向学生或受众进行免费引用,展示或者讲述,无须取得作者同意。

不允许以电子/纸质出版为目的进行摘抄或改编。

如图2-6所示,最高的1位(第31位)用做符号位,接着的 8 位(第23-30位)是指数E,剩下的 23 位(第0-22位)为有效数字 M。

【C/C++】 浮点数的存储结构以及与之相关的存储误差观察

图2-6 float的存储结构

相对于float,double类型使用8个字节来存储一个浮点数,它的储值范围以及精度都会高一些。习惯上,我们称float为单精度浮点数,double为双精度浮点数。所有的浮点数类型都是有符号的。

受限于有效数字的位数,浮点数的精度受到限制,会存在微小的误差。为了观察float与double的精度差异及其存储误差,我们创建一个Plain C Application,并修改main.c如下:

//Project - FloatError
#include <stdio.h>
 
int main(){
    float f = 0.00001;
    printf("The stored value of 0.00001 with float:   %.30f\n",f);
   
    double d = 0.00001;
    printf("The stored value of 0.00001 with double:   %.30f\n",d);
   
    f = f * 99000;
    if (f==0.99)
        printf("f*99000 == 0.99");
     else
         printf("f*99000 <> 0.99");
   
     return 0;
   }

上述代码的执行结果为:

The stored value of 0.00001 with float:   0.000009999999747378751600000000
The stored value of 0.00001 with double:   0.000010000000000000001000000000
f*99000 <> 0.99

代码第6,第9行的输出结果表明,0.00001存储至浮点数内,均有微弱误差,但double双精度浮点数的误差显然比float要小。

第12 ~ 15行是后面章节要讨论的条件分支语句▲,其语义可以简单理解为“如果… 则… 否则…”。当12行括号内的条件判断成立时,执行第13行,否则,执行第15行。(f==0.99)中的==号用于判断两端的值是否相等,如果相等,表示逻辑真,否则为逻辑假。从执行结果可以看出,由于存储误差的原因,与预期不符,上述相等判断被认为是假的,第15行代码被执行。

注 意

一般不要对浮点数进行逻辑相等判断,误差的存在会导致意料之外的结果。很多IDE环境会对上述代码的第12行发出警告:浮点数之间进行==,!= 判断▲是危险的。

本案例节选自作者编写的教材及配套实验指导书。

《C++编程基础及应用》(高等教育出版社,出版过程中)

Python编程基础及应用》,高等教育出版社

《Python编程基础及应用实验教程》,高等教育出版社

【C/C++】 浮点数的存储结构以及与之相关的存储误差观察

高校教师同行如果期望索取样书,教学支持资料,加群,请私信作者,联系时请提供学校及个人姓名为盼,各高校在读学生勿扰为谢。

青少年读者们如果期望系统性地学习Python及C/C++程序设计语言,欢迎尝试下述今日头条(西瓜)免费视频课程。

C/C++从入门到放弃(重庆大学现场版)

Python编程基础及应用(重庆大学现场版)

【C/C++】 浮点数的存储结构以及与之相关的存储误差观察

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/51229.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信