Fortran中实数的精确问题

时间:2012-04-04 17:26:06

标签: fortran precision gfortran real-datatype

我一直在尝试使用Fortran作为我的研究项目,使用GNU Fortran编译器(gfortran),最新版本, 但我在处理实数方面遇到了一些问题。如果您有代码:

program test
implicit none

real :: y = 23.234, z

z = y * 100000
write(*,*) y, z

end program

你会得到输出:

23.23999    2323400.0 

我觉得这很奇怪。 有人能告诉我这里到底发生了什么吗?看看z我可以看到y确实保留了它的精度,所以对于我认为应该不成问题的计算。但是为什么y的输出与我指定的值不完全相同,我能做些什么才能使它完全相同?

4 个答案:

答案 0 :(得分:10)

这不是问题 - 你所看到的只是计算机中数字的浮点表示。计算机无法准确处理实数,只能接近它们的近似值。关于这一点的好读物可以在这里找到:What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 1 :(得分:2)

只需将real替换为double precision,就可以在大多数平台上将有效小数位数从大约6个增加到大约15个。

答案 2 :(得分:1)

一般问题不仅限于Fortran,而是在有限精度的另一个基础上表示基数为10的实数。这里多次询问这个计算机科学问题。

对于特定的Fortran方面,声明“real”可能会给你一个精度浮点。将表示常量为“23.234”而没有类型限定符。没有小数点的常量“100000”是一个整数,因此表达式“y * 100000”导致整数隐式转换为实数,因为“y”是一个实数变量。

对于之前对这些问题的讨论,请参阅Extended double precision Fortran: integer*4 vs integer(4) vs integer(kind=4)Is There a Better Double-Precision Assignment in Fortran 90?

答案 3 :(得分:1)

这里的问题不在于Fortran,实际上它根本不是问题。这只是浮点运算的一个特性。如果你考虑如何将23.234表示为二进制中的“单个浮点数”,你会发现该数字必须保存为只有这么多精度的小数。

关于浮点数的要记住的事情是:看起来很圆的数字,甚至在基数10中也许不会用二进制

有关浮点主题的简要概述,请查看Wikipedia文章。有关非常详尽的解释,请查看Goldberg的规范paper(PDF)。