双精度值的精度错误

EL *_*ine 0 c++ double fortran fortran77

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

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

R12 = sqrt(95699.68D0+1123.6D0*flx) - 408.99D0
Run Code Online (Sandbox Code Playgroud)

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

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

R12 = sqrt(95699.68+1123.6*flx) - 408.99 ; 
Run Code Online (Sandbox Code Playgroud)

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

你们能帮助我找到这种差异的来源,因为对我的工作来说,确保精确度非常重要

Ale*_*ogt 5

使用双精度,您有52位(大约15位小数)的有效位精度.在你的情况下,这是:

Fortran语言:

0.14997522253177789e3
                ^
Run Code Online (Sandbox Code Playgroud)

C++

0.14997522253177794e3
                ^
Run Code Online (Sandbox Code Playgroud)

您可以看到两个结果都是相同的,直到第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
Run Code Online (Sandbox Code Playgroud)

结果是

 Default   149.97522253177794     
 UP        149.97522253177795     
 DOWN      149.97522253177794     
 ZERO      149.97522253177794     
 NEAREST   149.97522253177794  
Run Code Online (Sandbox Code Playgroud)