双精度值的精度错误

时间:2015-05-26 13:41:11

标签: c++ fortran double fortran77

我需要将Fortran代码转换为C ++代码,我遇到以下问题:

我尝试使用Fortran 77和C ++语言计算名为R12的双精度值,但我获得了两个彼此非常接近的值但具有两个不同的精度。这是我的Fortran代码:

R12 = sqrt(95699.68D0+1123.6D0*flx) - 408.99D0

double flx = 192.9D0。我获得的值是R12 = 149.97522253177789

我对C ++做同样的事情:

R12 = sqrt(95699.68+1123.6*flx) - 408.99 ; 

我在这里获得的价值是R12 = 149.97522253177794

请你们帮我找一下这个差异的来源,因为我的工作对于确保精确度非常重要

1 个答案:

答案 0 :(得分:5)

使用双精度,有52 bits (roughly 15 decimals)有效精度。在你的情况下,这是:

的Fortran:

0.14997522253177789e3
                ^

C ++

0.14997522253177794e3
                ^

您可以看到两个结果相同,直到第15位。我的猜测是C ++和Fortran对十进制系统应用了不同的转换(舍入)。

在Fortran 2003+中,您可以为ROUND提供write说明符:

program test

  write(*,*)                     'Default    ', sqrt(95699.68D0+1123.6D0*192.9D0) - 408.99D0
  write(*,*,round='UP')          'UP         ', sqrt(95699.68D0+1123.6D0*192.9D0) - 408.99D0
  write(*,*,round='DOWN')        'DOWN       ', sqrt(95699.68D0+1123.6D0*192.9D0) - 408.99D0
  write(*,*,round='ZERO')        'ZERO       ', sqrt(95699.68D0+1123.6D0*192.9D0) - 408.99D0
  write(*,*,round='NEAREST')     'NEAREST    ', sqrt(95699.68D0+1123.6D0*192.9D0) - 408.99D0

end program

结果

 Default   149.97522253177794     
 UP        149.97522253177795     
 DOWN      149.97522253177794     
 ZERO      149.97522253177794     
 NEAREST   149.97522253177794