简体   繁体   English

Fortran和MATLAB之间的数值精度问题

[英]Issues with numerical precision between Fortran and MATLAB

NOTE: Any solutions or work arounds to this issue need to occur in the MATLAB, it is the code where the issues arise. 注意: 此问题的任何解决方案或解决方案都需要在MATLAB中进行,这是出现问题的代码。 Making the fortran match the MATLAB is counter productive because then neither piece of code will work... I understand that the difference is because of differences in the way the fortran compiler and whatever the hell MATLAB does in place of compiling interpret single versus double precision floats but I am hoping that someone can help me come up with a solution to work around this. 使fortran与MATLAB匹配会适得其反,因为那段代码都将无法工作...我理解,差异是由于fortran编译器的方式不同以及MATLAB在代替编译解释单精度与双精度方面所做的一切浮动,但我希望有人可以帮助我提出解决方案。

I am working on debugging some code that I have translated from Fortran into MATLAB and have come across something that has me stumped. 我正在调试一些从Fortran转换为MATLAB的代码,并且遇到了让我感到困惑的事情。 In both fortran and MATLAB I have the following line 在fortran和MATLAB中,我都有以下内容

pcnt = 0.9999*(-0.5+z2)

where z2 = 0.51482129528868548 . 其中z2 = 0.51482129528868548 The issue I am having is that there is a difference of 2.4594e-10 in the pcnt calculated in MATLAB and the pcnt calculated in fortran. 我遇到的问题是,在MATLAB中计算出的pcnt与在fortran中计算出的2.4594e-10存在2.4594e-10的差异。 I have confirmed that z2 is precisely the same (ie z2_matlab-z2_fortran=0 ) and so I am stumped. 我已经确认z2完全相同(即z2_matlab-z2_fortran=0 ),所以我很z2_matlab-z2_fortran=0 both z2 and pcnt are double precision ( real*8 for fortran) in both Fortran and MATLAB so as far as I am concerned they should have exactly the same accuracy (since this is being run on the same machine). 在Fortran和MATLAB中,z2和pcnt都具有双精度(对于Fortran,为real*8 ),因此就我而言,它们应该具有完全相同的精度(因为这是在同一台计算机上运行的)。

Normally I wouldn't care about a difference this small but z2 ends up getting multiplied by a large number, which is then used to calculate an index later on and the small difference ends up being a difference of around 2 for the array index later, leading to huge errors later on in the algorithm (on the order of 1e6 for number that are only at most order 1e7). 通常情况下,我不会关心这么小的差异,但是z2最终会乘以一个大数,然后再用于计算索引,而该小差异最终会导致数组索引的差异约为2,导致算法稍后出现巨大错误(数量最多为1e7的数量大约为1e6)。

Does anyone have any idea why this issue is happening and some way to fix it? 有谁知道为什么会发生此问题,并有某种解决方法? I am performing this work on MATLAB R2011a and used the gfortran compiler to compile the fortran all on a 64 bit MacBook pro with an I5 (3rd gen I think) processor. 我正在MATLAB R2011a上执行此工作,并使用gfortran编译器在具有I5(我认为是第三代)处理器的64位MacBook Pro上编译了所有fortran。

If someone has any suggestions please let me know because if I can't find a solution to this all of the translation of some 5000 lines of code I performed over the last two weeks would be pretty much worthless otherwise. 如果有人有任何建议,请告诉我,因为如果找不到解决方案,那么我在过去两周中执行的大约5000行代码的全部翻译将毫无价值。

Also, any solutions would have to be to the MATLAB code because the Fortran code is the one that currently works. 同样,任何解决方案都必须针对MATLAB代码,因为Fortran代码是当前可用的代码。

Thanks in advance, 提前致谢,

Andrew 安德鲁

The Fortran numeric literals are single precision unless the d modifier used, while MATLAB uses double as default numeric literal type. 除非使用d修饰符,否则Fortran数字文字是单精度的,而MATLAB使用double作为默认数字文字类型。 So maybe you should rewrite your pcnt expression like: 因此,也许您应该像这样重写pcnt表达式:

pcnt = 0.9999d+0 * (-0.5d+0 + z2)

Conversely, you should convert to single the numeric literals of MATLAB, in order to emulate the Fortran behaviour: 相反,为了模拟Fortran行为,应将MATLAB的数字文字转换为单个数字文字:

pcnt = single(0.9999) * (single(-0.5) + z2);

Later edit 以后编辑

In extremis, one should not rely on the different compilers' algorithms of interpreting numeric literals; 在极端情况下,不应依赖于不同编译器解释数字文字的算法。 but instead use the native (binary) representation of the said literals: 而是使用上述文字的本机(二进制)表示形式:

  • write unformatted from Fortran all the numeric literals that cause you grief (in this formula, 0.9999 is the most probable suspect, because 0.5 can be represented exactly in both FP precision), in a file (see WRITE ). 在文件中用Fortran格式格式化所有引起麻烦的数字文字(在此公式中,最有可能是0.9999,因为在FP精度中都可以精确表示0.5)(请参阅WRITE )。
  • load in MATLAB these values stored in the file (see fread() ). 将存储在文件中的这些值加载到MATLAB中(请参阅fread() )。
  • use the loaded values instead of numeric literals (which should have a suggestive name, as a good programming practice). 使用加载的值而不是数字文字(作为良好的编程习惯,应使用提示性名称)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM