将工作代码从双精度转换为四精度:如何从输入文件中读取 FORTRAN 中的四精度数字
Posted
技术标签:
【中文标题】将工作代码从双精度转换为四精度:如何从输入文件中读取 FORTRAN 中的四精度数字【英文标题】:Converting a working code from double-precision to quadruple-precision: How to read quadruple-precision numbers in FORTRAN from an input file 【发布时间】:2013-08-08 22:17:31 【问题描述】:我有一个大而古老的 FORTRAN 77 代码,它已经运行了很多年,没有任何问题。 双精度已经不够用了,所以要转换成四精度我有:
-
将所有出现的 REAL8 替换为 REAL16
将 DCOS() 等所有函数替换为 COS() 等函数
将所有内置数字替换为 0.d0 到 0.q0 和 1D+01 到 1Q+01
使用 gcc-4.6 编译器编译程序没有错误或警告
-
操作系统:openSUSE 11.3 x86_64(64 位操作系统)
硬件:Intel Xeon E5-2650(Sandy Bridge)
我的 LD_LIBRARY_PATH 变量设置为 64 位库文件夹: /gcc-4.6/lib64
程序读取一个包含数字的输入文件。 这些数字曾经是 1.234D+02 的形式(适用于代码的双精度版本)。 我已经改变了它们,所以现在这个数字是 1.234Q+02 ,但是我得到了运行时错误:
列表输入的第 1 项中的实数错误
表示从输入文件中读取数据的子程序(称为read.f)没有找到输入文件中的第一个数字,与预期的兼容。
奇怪的是,当输入文件包含 1.234D+02 或 123.4 之类的数字(根据输出似乎自动转换为形式 1.234D+02 而不是 Q+02),它只是不喜欢 Q+02 ,所以 gcc-4.6 似乎不允许从科学计数法的输入文件中读取四精度数字!
有没有人能够在 FORTRAN 中使用 gcc 编译器从输入文件中读取科学记数法的四精度数(例如 1234Q+02),如果是,您是如何让它工作的? ? (或者您是否需要不同的编译器/操作系统/硬件才能使其工作?)
【问题讨论】:
您似乎将源中特定类型的实数的文本表示与输入文件中实际数据的文本表示混为一谈。输入文件中无需使用不同的指数字符 - 只需使用 E。Fortran 处理器(此处由编译器的运行时库表示)会将输入文件中的文本表示转换为程序使用的任何适当的内部表示。 这正是您应该使用种类符号(real(wp)
和 1._wp
)的问题。然后,您只需将顶部模块中的 wp
调整为您当前需要的任何内容。
感谢@IanH!我将输入文件中的所有 Q 更改为 D,然后程序运行。我留下了这个问题,因为我仍然希望我的程序能够在 12Q+01 中读取,因为我的输入文件是由另一个程序生成的。我是否也可以将所有硬编码数字(如 1.234D+02)保留在实际的 .f 文件中,作为 D+02 而不是 Q+02,并依靠编译器将它们转换为四倍精度,基于以下事实它们各自的变量是 REAL*16 吗?我真的很想只有一个代码用#define 控制 REAL*8 和 REAL*16 的选择,并且没有其他更改。
过了这么长时间,你真的应该问一个新问题了。你有几个语法错误。
不,问一个新问题。
【参考方案1】:
@IanH 和@Vladimi 几乎所有这些都已在 cmets 中。
我建议在您的 FORTRAN 77 代码中混入一点 Fortran 90。
用“E”写下你所有的数字。更改您的其他程序以这种方式写入数据。不要打扰“D”,也不要尝试使用不经常支持的“Q”。 (在源代码的常量中使用“Q”是 gfortran 的扩展——参见手册中的 6.1.8。)
由于您希望相同的源代码支持两种精度,因此在程序顶部有:
use ISO_FORTRAN_ENV
WP = real128
或
use ISO_FORTRAN_ENV
WP = real64
作为改变您的代码使用双精度还是四精度的变体。这是使用 ISO Fortran 环境按位数选择类型。 (use
需要在program
和implicit none
之间;implicit none
后面的赋值语句。)
然后通过以下方式声明您的真实变量:
real (WP) :: MyVar
在源代码中,将实常数写为1.23456789012345E+12_WP
。 _type
是 Fortran 90 指定常量类型的方法。这样,您只需更改定义 WP
的单行即可在双精度和四倍精度之间来回切换
WP == 工作精度。
只需在输入文件中使用“E”即可。 Fortran 会根据变量的类型进行读取。
为什么不写一个小测试程序来试试呢?
【讨论】:
亲爱的 M. S. B.,我尝试了一个非常简单的代码(请参阅原始问题底部的扩展名)。它在编译时给出错误。您能给我们一个最低限度的工作示例吗?以上是关于将工作代码从双精度转换为四精度:如何从输入文件中读取 FORTRAN 中的四精度数字的主要内容,如果未能解决你的问题,请参考以下文章
为啥Java在使用“加号”运算符时会执行从双精度到整数的隐式类型转换? [复制]