我在FORTRAN中有一个有限体积模拟代码,它对数组中相邻元素之间的差异非常敏感。我只使用双精度值和常量。
由于在非常复杂的计算过程中出现一些舍入误差(涉及大量矩阵运算),我得到的结果与机器精度稍高一些,例如
。before: 1.000000000000000 514 e-1
after: 1.000000000000059 985 e-1
(示例性值)
由于这些舍入错误对于我的数组中的每个元素都不同,现在有不同的条目,尽管最初所有条目具有相同的值。这导致我的代码现在"看到"相邻的值不再相等,并开始对这些差异进行操作,放大它们。经过数千次评估后,这种人工振荡开始增长并主导解决方案。
可能的补救措施可能是通过设置最低值来限制计算值的准确性。 10位到零。这将在第一个操作中引入错误,但稍后会有效地抑制任何可能的舍入错误。它仍然比32位浮点变量准确得多。我不在乎丢失第10位的准确度。
有没有办法限制FORTRAN中变量的准确性?
注意:我使用ifort
版本14.0.2并使用参数-r8
进行编译。
答案 0 :(得分:1)
对你的问题的简短回答是不,Fortran不会在这个上保存你的皮肤,不是通过巧妙地使用编译器选项或选择准神话的48位fp数来计算的
在这方面,Fortran与用于解决此类问题的大多数其他编程语言没有什么不同。与它们一样,它使用的f-p算法是(a)IEEE-754定义的算法和(b)实际在计算机硬件上实现的接近该模型的东西。您通常可以通过编译器选项在两者之间进行选择 - 除非您另外说明,否则Fortran自己的f-p模型不是完全IEEE,并且将依赖于底层硬件上的一些基本操作。
所以选择以下之一:
10e-100
下的所有数字切换为0
,或者建议您至少设置为0
- 每个结果上的重要位置)并以科学的方式证明你喜欢哪种方式(我们都这样做,它可能是可耻的,但有时它是唯一可行的事情); 如果选择选项2,现代Fortran提供了一整套比特错误的例程,例如ibclr
,ibset
,iand
,ior
等。不要让它们采用整数输入这一事实让你失望,在类型之间进行狡猾的强制转换有内在的transfer
。此外,如果您还没有这样做,那么在熟悉Fortran的boz-literal-constants
时,您将值得一试。