Fortran Coder

查看: 9990|回复: 4
打印 上一主题 下一主题

[数值问题] 简单的减法,release和debug的计算结果为什么不一样?

[复制链接]

4

帖子

1

主题

0

精华

入门

F 币
34 元
贡献
21 点
跳转到指定楼层
楼主
发表于 2019-5-21 20:58:40 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
采用Fortran双精度计算c=c1^2 - (c3^2)*c2,分别用debugrelease模式编译出可执行程序,编译器是intel Parallel Studio XE 2018。运行后发现计算结果在小数点最后一位(第15位)上不一样。
于是输出c1,c2和c3检查差异的来源。虽然双精度的有效位数是小数点后15位,但是强制输出小数点后18位。结果显示c1,c2和c3在两种模式中直到小数点后18位都完全相同,但是(c3^2)*c2的结果却出现差异。

数据如下,黑色加粗部分表示15位小数点。
c1=3.745496116952728386E-04,  c2=2.364288313097455060E-03,  c3=7.071067835889063291E-01,

c1^2在两种模式下结果完全一样,等于    3.745496116952728386E-04
(c3^2)*c2在两种模式中分别等于debug: 1.182144164581275247E-03,   release: 1.182144164581275031E-03,
相减得到c在两种模式中分别等于debug: -8.075945528860024088E-04, release: -8.075945528860021920E-04。

(c3^2)*c2的差异出现在16位及以后,但是影响到了c的第十五位。说明16位以后的数字也参与了计算,并对结果产生了影响。
那么问题来了,
1. 双精度只能保存到小数点后15位,16到18位的小数点是怎么来的,为什么能参与计算?
2.两种模式中c1, c2和c3直到小数点18位完全一样,为什么通过乘法运算得到的(c3^2)*c2在小数点后第16位上出现差异?

分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

4

帖子

1

主题

0

精华

入门

F 币
34 元
贡献
21 点
沙发
 楼主| 发表于 2019-5-22 11:24:42 | 显示全部楼层
fcode 发表于 2019-5-22 08:58
这都很正常呀。
因为计算机是二进制。

多谢回复,第一个问题我大概理解了

4

帖子

1

主题

0

精华

入门

F 币
34 元
贡献
21 点
板凳
 楼主| 发表于 2019-6-4 20:23:20 | 显示全部楼层
pasuka 发表于 2019-5-25 11:21
lz需要了解IEEE-754和IEEE-754 (2008)规范对于计算机浮点数的约定
传送门:
https://docs.oracle.com/cd/E7 ...

厉害,有空学习一下
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-5 05:39

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表