博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
<float.h>中DBL_TRUE_MIN的定义和作用
阅读量:7026 次
发布时间:2019-06-28

本文共 2870 字,大约阅读时间需要 9 分钟。

在学习C Prime Plus的过程中遇到了这道复习题,利用搜索引擎加上自己的一些思考,初步得出了结论,如有谬误之处,还望不吝赐教

下列循环中,如果valuedouble类型,会出现什么问题?

for (value = 36; value > 0; value /= 2)  printf("%3d", value);

推测运行结果:如果valuedouble类型,计算过程中会导致无限循环(直到超过double类型的精度表示范围),又因printf以整型形式打印数字,会在最后出现很多个数字0

答案中指明了这种现象的名词:浮点数下溢(underflow)

实际运行结果:

...(很多个0)0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 0  0  0  0  0-21474836481073741824536870912-1879048192120795955260397977630198988815099494475497472377487361887436894371844718592235929611796485898242949121474567372836864184329216460823041152576288144 72 36 18  9  4  2  1请按任意键继续.. .

确实出现了很多个0,但是在很多个0的后面又莫名其妙多出了一堆整数。为了分离出后面的长数字,修改格式化字符串为" %3d",结果如下:

...(很多个0)0   0   0   0   0 -2147483648 1073741824 536870912 -1879048192 1207959552 603979776 301989888 150994944 75497472 37748736 18874368 9437184 4718592 2359296 1179648 589824 294912 147456 73728 36864 18432 9216 4608 2304 1152 576 288 144  7236  18   9   4   2   1请按任意键继续. . .

为了进一步弄清楚产生这种现象的原因,继续修改格式化字符串为" %.3le",结果如下:

...  4.663e-317 2.331e-317 1.166e-317 5.828e-318 2.914e-318 1.457e-318 7.285e-319 3.643e-319 1.821e-319 9.107e-320 4.553e-320 2.277e-320 1.138e-320 5.692e-321 2.846e-321 1.423e-321 7.115e-322 3.557e-322 1.779e-322 8.893e-323 4.447e-323 1.976e-323 9.881e-324 4.941e-324请按任意键继续. . .

可以看到,以整型输出的double类型变量实际上一直在减小,应该是double在内存中被截断读取为int之后导致了显示为整数的情况。

查看<float.h>头文件,找到两个和double类型精度有关的明示常量:

#define DBL_MIN          2.2250738585072014e-308 // min positive value#define DBL_TRUE_MIN     4.9406564584124654e-324 // min positive value

可以看出,导致循环终止的原因是,循环中最后一个数字4.941e-324除以2之后的结果小于DBL_TRUE_MIN的值

为什么<float.h>中要采用DBL_MINDBL_TRUE_MIN两个具有相同注释的常量?我首先利用搜索引擎查到了这样一个带注释的版本:

#ifndef DBL_TRUE_MIN/* DBL_TRUE_MIN is a common non-standard extension for the minimum denorm value * DBL_MIN is the minimum non-denorm value -- use that if TRUE_MIN is not defined */#define DBL_TRUE_MIN DBL_MIN#endif

注释部分大意为,DBL_TRUE_MIN是对最小非规格化浮点数的通用非标准扩充,而DBL_MIN才是最小非规格化浮点数的值,并且只在DBL_TRUE_MIN未定义时使用。

C11标准 §5.2.4.2.2.13中提到了DBL_TRUE_MIN

The values given in the following list shall be replaced by constant expressions with implementation-defined (positive) values that are less than or equal to those shown:

— minimum normalized positive floating-point number, bemin−1
FLT_MIN 1E-37
DBL_MIN 1E-37
LDBL_MIN 1E-37
— minimum positive floating-point number
FLT_TRUE_MIN 1E-37
DBL_TRUE_MIN 1E-37
LDBL_TRUE_MIN 1E-37
(If the presence or absence of subnormal numbers is indeterminable, then the value is intended to be a positive number no greater than the minimum normalized positive number for the type.)

根据上面查到的信息,我得出了以下的结论:

首先,浮点数在计算机中有规格化数和非规格化数两种表示方式。C标准在这里规定了两种浮点数的最小正值。具体值的大小是由实现来定义的(由编译器等来决定),但是不得小于列出的这些值。并且,如果没有确定非规格化数是否会出现,DBL_TRUE_MIN的值应该是一个小于等于该类型最小正规格化数DBL_MIN的值,FLT_TRUE_MINLDBL_TRUE_MIN同理。

本来想快点看完这本书的,结果遇到一个弄不懂的问题就查了很长时间……这个其实并不是一个好习惯。不过,反正我自己已经查过了,可能有很多个人理解不正确的地方,但是如果可以帮助到其他人,我发到这里的目的就达到了

转载地址:http://bxpxl.baihongyu.com/

你可能感兴趣的文章
SFB 项目经验-30-SFB与SFB联盟-IM-正常-状态-不正常
查看>>
Linux如何在系统运行过程中修改内核参数
查看>>
配套自测连载(八)
查看>>
日期格式化大全
查看>>
Windows 8产品重置次数
查看>>
《IT人生需要指引》读后感(学生作业分享)
查看>>
SANS:2012年度日志管理调查报告
查看>>
《MySQL管理之道:性能调优、高可用与监控》china-pub首发!
查看>>
Tip:启用完exchange CAS Array之后的注意事项
查看>>
新浪娱乐前总监的辞职信:再见,新浪!
查看>>
MyBaits关联查询一对一、一对多
查看>>
网网互联,充分、合理的利用现有网络资源
查看>>
如何手工删除AD RMS SCP?
查看>>
Lync Server 2013企业版部署系列之五:前端服务器软件准备
查看>>
双活数据中心实现业务零中断
查看>>
Wijmo 更优美的jQuery UI部件集:活动日历控件(Event Calendar)
查看>>
艾伟_转载:面向对象封装了啥
查看>>
与马克&#183;扎克伯格共事,互联网营销
查看>>
.NET 动态脚本语言Script.NET 入门指南 Quick Start
查看>>
[观点]微软报告称开源更昂贵
查看>>