在FORTRAN

时间:2015-12-03 15:30:06

标签: floating-point fortran precision

我在FORTRAN中有一个有限体积模拟代码,它对数组中相邻元素之间的差异非常敏感。我只使用双精度值和常量。

由于在非常复杂的计算过程中出现一些舍入误差(涉及大量矩阵运算),我得到的结果与机器精度稍高一些,例如

before: 1.000000000000000 514 e-1
after:  1.000000000000059 985 e-1

(示例性值)

由于这些舍入错误对于我的数组中的每个元素都不同,现在有不同的条目,尽管最初所有条目具有相同的值。这导致我的代码现在"看到"相邻的值不再相等,并开始对这些差异进行操作,放大它们。经过数千次评估后,这种人工振荡开始增长并主导解决方案。

可能的补救措施可能是通过设置最低值来限制计算值的准确性。 10位到零。这将在第一个操作中引入错误,但稍后会有效地抑制任何可能的舍入错误。它仍然比32位浮点变量准确得多。我不在乎丢失第10位的准确度。

有没有办法限制FORTRAN中变量的准确性?

注意:我使用ifort版本14.0.2并使用参数-r8进行编译。

1 个答案:

答案 0 :(得分:1)

对你的问题的简短回答是不,Fortran不会在这个上保存你的皮肤,不是通过巧妙地使用编译器选项或选择准神话的48位fp数来计算

在这方面,Fortran与用于解决此类问题的大多数其他编程语言没有什么不同。与它们一样,它使用的f-p算法是(a)IEEE-754定义的算法和(b)实际在计算机硬件上实现的接近该模型的东西。您通常可以通过编译器选项在两者之间进行选择 - 除非您另外说明,否则Fortran自己的f-p模型不是完全IEEE,并且将依赖于底层硬件上的一些基本操作。

所以选择以下之一:

  1. 按照上面@Ben建议的方法,添加 系统的一些物理属性,以限制其行为 更现实的东西;
  2. 修改您的代码,以对生成的数字实施纯编程约束(例如,将10e-100下的所有数字切换为0,或者建议您至少设置为0 - 每个结果上的重要位置)并以科学的方式证明你喜欢哪种方式(我们都这样做,它可能是可耻的,但有时它是唯一可行的事情);
  3. 使用高精度库将问题推迟到第128位(我不知道这对你来说是否足够好)或256号或者你有什么用;
  4. 使用任意精度的库(或软件)来获取所需的位数。
  5. 如果选择选项2,现代Fortran提供了一整套比特错误的例程,例如ibclribsetiandior等。不要让它们采用整数输入这一事实让你失望,在类型之间进行狡猾的强制转换有内在的transfer。此外,如果您还没有这样做,那么在熟悉Fortran的boz-literal-constants时,您将值得一试。