Fortran Coder

标题: 学习过程中遇到的一个关于单精度变量的问题 [打印本页]

作者: jojo    时间: 2019-8-23 14:02
标题: 学习过程中遇到的一个关于单精度变量的问题
[Fortran] 纯文本查看 复制代码
program ex0408
real a,b
a=1000
b=0.1
write(*,*)  a,"+",b,"=",a+b
stop
end



编译运行结果如下:
pcx@ubuntu:~/a/ab$ vim ex0408.f90
pcx@ubuntu:~/a/ab$ gfortran ex0408.f90
pcx@ubuntu:~/a/ab$ ./a.out
   1000.00000     +  0.100000001     =   1000.09998  


为什么我给b赋值0.1,但在运行的时候b变成了超过单精度浮点数有效位的0.100000001.
还望大佬们能给萌新解释一下。


作者: li913    时间: 2019-8-23 15:02
本帖最后由 li913 于 2019-8-23 15:23 编辑

我用ivf,没这个情况,但gfortran的确是这样,搞不懂。

QQ截图20190823150210.png (20.98 KB, 下载次数: 209)

QQ截图20190823150210.png

作者: jojo    时间: 2019-8-27 21:09
li913 发表于 2019-8-23 15:02
我用ivf,没这个情况,但gfortran的确是这样,搞不懂。

感谢回复。可能是精度的问题,我查了一下,对gfortran编译器来说,0.1和0.1d0是两个不同的数字,我把这个程序 第4行改成:b=0.1d0以后,输出结果精度高了很多:   
1.0000000000000000      +  0.10000000000000001      =   1.1000000000000001      b=  0.10000000000000001  

因为导师让我在Ubuntu环境下编程,所以用不了ivf,感觉ivf的编译器更人性化一点。


作者: vvt    时间: 2019-8-28 08:04
本帖最后由 vvt 于 2019-8-28 08:14 编辑

精度肯定影响这个问题的。
不只是 0.1 和 0.1d0 不一样(常量的精度),变量也需要定义为相同的精度类型(kind=8之类的)

ivf和gfortran的不同在于:用表控格式输出write(*,*),对单精度(实际只有7位有效数字),gfortran会默认输出9个有效数字。但ivf只默认7个
[Fortran] 纯文本查看 复制代码
program ex0408
real a,b
real(8) a2,b2
a=1000
b=0.1
a2=1000d0
b2=0.1d0
write(*,*)  a,"+",b,"=",a+b
write(*,'(3(f10.5,a))')  a,"+",b,"=",a+b
write(*,'(3(es13.6,a))')  a,"+",b,"=",a+b
write(*,*)  a2,"+",b2,"=",a2+b2
end

所以你感觉ivf和gfortran精度不同而已。
实际上,你查看两者结果的二进制,是一样的。
或者用 es13.6 查看,也是一样的
(楼主可以用ivf和gfortran分别编译运行以上代码,对比查看)

作者: jojo    时间: 2019-9-2 08:42
vvt 发表于 2019-8-28 08:04
精度肯定影响这个问题的。
不只是 0.1 和 0.1d0 不一样(常量的精度),变量也需要定义为相同的精度类型(k ...

非常感谢




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2