我可以使用 `real(wp)` 在 Fortran 中获得更高的准确性吗?
Will I get more accuracy in Fortran with `real(wp)`?
通过替换所有代码,我的代码是否更加准确:
real(dl) variable1
通过在每个 Fortran90 源文件的开头放置 :
integer, parameter :: wp = selected_real_kind(15,307)
并像这样声明变量:
real(wp) variable1
更新 1
你是对的,一个简单的程序给出:
program main
implicit none
integer, parameter :: dl = KIND(1.d0)
integer, parameter :: wp = selected_real_kind(15,307)
real(kind=dl) :: dl_number
real(kind=wp) :: wp_number
write(*,*) 'epsilon for dl number', epsilon(dl_number)
write(*,*) 'precision for dl number', precision(dl_number)
write(*,*) 'epsilon for wp number', epsilon(wp_number)
write(*,*) 'precision for wp number', precision(wp_number)
stop
end
输出:
epsilon for dl number 2.2204460492503131E-016
precision for dl number 15
epsilon for wp number 2.2204460492503131E-016
precision for wp number 15
所以没必要用wp = selected_real_kind(15,307)
代替dl = KIND(1.d0)
。
总号
有两个问题:
wp比dl精度高吗?这取决于编译器和平台。
浮点数精度的提高是否提高了数值结果?在某些情况下,准确性受到算法或数据的限制,除了较慢的程序之外,您什么也得不到。
作为第一个诊断,无论如何,执行
write(*,*) 'dl =', dl
write(*,*) 'wp =', wp
看种类是不是真的一样
然后,您可以获得关于种类的一些信息:
real(kind=dl) :: dl_number
real(kind=wp) :: wp_number
write(*,*) 'epsilon for dl number', epsilon(dl_number)
write(*,*) 'precision for dl number', precision(dl_number)
write(*,*) 'epsilon for wp number', epsilon(wp_number)
write(*,*) 'precision for wp number', precision(wp_number)
epsilon
return 是该种类的最小可表示数,precision
小数精度。
无论如何,您应该了解您的计算和工作所需的精度。
正如 albert 和 Ian Bush 所指出的,代码中还有许多其他地方需要检查数值表示的问题。
- 文字常量需要特别小心。例如,
1.0/3.0
和 1._wp/3._wp
具有明显不同的值。
- 某些函数还将 return 默认实数值(即单精度),除非有要求,例如
real
内在函数。
- ...
通过替换所有代码,我的代码是否更加准确:
real(dl) variable1
通过在每个 Fortran90 源文件的开头放置 :
integer, parameter :: wp = selected_real_kind(15,307)
并像这样声明变量:
real(wp) variable1
更新 1
你是对的,一个简单的程序给出:
program main
implicit none
integer, parameter :: dl = KIND(1.d0)
integer, parameter :: wp = selected_real_kind(15,307)
real(kind=dl) :: dl_number
real(kind=wp) :: wp_number
write(*,*) 'epsilon for dl number', epsilon(dl_number)
write(*,*) 'precision for dl number', precision(dl_number)
write(*,*) 'epsilon for wp number', epsilon(wp_number)
write(*,*) 'precision for wp number', precision(wp_number)
stop
end
输出:
epsilon for dl number 2.2204460492503131E-016
precision for dl number 15
epsilon for wp number 2.2204460492503131E-016
precision for wp number 15
所以没必要用wp = selected_real_kind(15,307)
代替dl = KIND(1.d0)
。
总号
有两个问题:
wp比dl精度高吗?这取决于编译器和平台。
浮点数精度的提高是否提高了数值结果?在某些情况下,准确性受到算法或数据的限制,除了较慢的程序之外,您什么也得不到。
作为第一个诊断,无论如何,执行
write(*,*) 'dl =', dl
write(*,*) 'wp =', wp
看种类是不是真的一样
然后,您可以获得关于种类的一些信息:
real(kind=dl) :: dl_number
real(kind=wp) :: wp_number
write(*,*) 'epsilon for dl number', epsilon(dl_number)
write(*,*) 'precision for dl number', precision(dl_number)
write(*,*) 'epsilon for wp number', epsilon(wp_number)
write(*,*) 'precision for wp number', precision(wp_number)
epsilon
return 是该种类的最小可表示数,precision
小数精度。
无论如何,您应该了解您的计算和工作所需的精度。
正如 albert 和 Ian Bush 所指出的,代码中还有许多其他地方需要检查数值表示的问题。
- 文字常量需要特别小心。例如,
1.0/3.0
和1._wp/3._wp
具有明显不同的值。 - 某些函数还将 return 默认实数值(即单精度),除非有要求,例如
real
内在函数。 - ...