Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran与MATLAB之间的数值精度问题_Matlab_Fortran_Precision_Gfortran - Fatal编程技术网

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

Fortran与MATLAB之间的数值精度问题,matlab,fortran,precision,gfortran,Matlab,Fortran,Precision,Gfortran,注意:此问题的任何解决方案或解决方法都需要在MATLAB中出现,问题产生的代码。使fortran与MATLAB匹配会适得其反,因为这样两段代码都不能工作。。。我理解这种差异是因为fortran编译器和MATLAB在编译解释单精度浮点和双精度浮点方面的不同,但我希望有人能帮助我找到解决方案 我正在调试一些从Fortran翻译成MATLAB的代码,遇到了一些让我困惑的问题。在fortran和MATLAB中,我有以下几行代码 pcnt = 0.9999*(-0.5+z2) 其中z2=0.514821

注意:此问题的任何解决方案或解决方法都需要在MATLAB中出现,问题产生的代码。使fortran与MATLAB匹配会适得其反,因为这样两段代码都不能工作。。。我理解这种差异是因为fortran编译器和MATLAB在编译解释单精度浮点和双精度浮点方面的不同,但我希望有人能帮助我找到解决方案

我正在调试一些从Fortran翻译成MATLAB的代码,遇到了一些让我困惑的问题。在fortran和MATLAB中,我有以下几行代码

pcnt = 0.9999*(-0.5+z2)
其中
z2=0.51482129528868548
。我遇到的问题是,在MATLAB中计算的pcnt与在fortran中计算的pcnt之间存在差异
2.4594e-10
。我已经确认z2是完全相同的(即
z2_matlab-z2_fortran=0
),所以我被难住了。在fortran和MATLAB中,z2和pcnt都是双精度(
real*8
fortran),就我而言,它们应该具有完全相同的精度(因为这是在同一台机器上运行的)

通常我不关心这么小的差异,但是z2最终会被一个大的数字乘以,这个大的数字随后会被用来计算索引,而这个小的差异最终会成为数组索引的2左右的差异,导致算法中的巨大错误(对于最多为1e7级的编号,顺序为1e6)

有没有人知道为什么会出现这个问题,以及解决这个问题的方法?我正在MatlabR2011A上执行这项工作,并使用gfortran编译器在64位MacBook pro上编译fortran,所有这些都是使用I5(我想是第三代)处理器

如果有人有任何建议,请让我知道,因为如果我找不到解决方案,我在过去两周执行的大约5000行代码的所有翻译都将毫无价值

此外,任何解决方案都必须使用MATLAB代码,因为Fortran代码是目前有效的代码

提前感谢,


Andrew

除非使用
d
修饰符,否则Fortran数值文本是单精度的,而MATLAB使用
double
作为默认数值文本类型。因此,也许您应该重写
pcnt
表达式,如下所示:

pcnt = 0.9999d+0 * (-0.5d+0 + z2)
相反,为了模拟Fortran的行为,您应该将MATLAB的数值文字转换为单个:

pcnt = single(0.9999) * (single(-0.5) + z2);
以后编辑

在极端情况下,不应依赖不同编译器的算法来解释数字文字;而应使用所述文字的本机(二进制)表示:

  • 从Fortran中无格式写入导致您悲伤的所有数字文字(在这个公式中,0.9999是最可能的可疑值,因为0.5可以在两个FP精度中精确表示),并写入一个文件(请参见
    write
  • 在MATLAB中加载存储在文件中的这些值(请参见
    fread()
  • 使用加载的值而不是数字文字(作为一种良好的编程实践,数字文字应该有一个提示性的名称)

除非使用
d
修饰符,否则Fortran数值文本是单精度的,而MATLAB使用
double
作为默认数值文本类型。因此,您可能应该重写
pcnt
表达式,如下所示:

pcnt = 0.9999d+0 * (-0.5d+0 + z2)
相反,为了模拟Fortran的行为,您应该将MATLAB的数值文字转换为单个:

pcnt = single(0.9999) * (single(-0.5) + z2);
以后编辑

在极端情况下,不应依赖不同编译器的算法来解释数字文字;而应使用所述文字的本机(二进制)表示:

  • 从Fortran中无格式写入导致您悲伤的所有数字文字(在这个公式中,0.9999是最可能的可疑值,因为0.5可以在两个FP精度中精确表示),并写入一个文件(请参见
    write
  • 在MATLAB中加载存储在文件中的这些值(请参见
    fread()
  • 使用加载的值而不是数字文字(作为一种良好的编程实践,数字文字应该有一个提示性的名称)

听起来您真正的问题可能是算法本身存在数值稳定性问题。话虽如此,您在每种情况下获得的
pcnt
的实际值是多少?可能重复的
0.9999
0.5
都声明为单精度。当将单精度数字存储为双精度时精度,编译器必须“猜测”最后一位。如果
z2
的顺序是
1e-1
,那么
1e-10
的差异是由最后一位造成的。显然,MATLAB对Fortran的猜测与Fortran不同。@PaulR我同意你的观点,但不幸的是,我无法控制这一点……坦率地说,Fortran代码的所有内容都做得很差,但同样,也存在一些问题对此我无能为力(这是它被翻译成MATLAB的原因之一。@AlexanderVogt我不同意这是一个重复的问题。这非常相似,但我想看看是否有人能帮助我解决这个问题。我同意你的第二个评论,但我希望找到一种解决方法。听起来你真正的问题可能是algorithm本身存在数值稳定性问题。话虽如此,在每种情况下,
pcnt
的实际值是多少?可能重复的
0.9999
0.5
都声明为单精度。当将单精度数字存储为双精度时,编译器必须“猜测”最后一位。如果
z2
的顺序为
1e-1
,则
1e-10
的差异是由于这些最后一位造成的。Obvi