用于溢出检测的 64 位浮点数的最大值

Maximum value of 64 bit floating point number for overflow detection

我有一个看似简单的问题:我想通过执行以下操作来检测 Fortran 中的浮点加法是否会溢出:

real*8 :: a, b, c

a = ! some value
b = ! some value

if (b > DOUBLE_MAX - a) then
  ! handle overflow
else
  c = a + b

问题是我不知道 DOUBLE_MAX 应该是什么。我知道浮点数是如何根据 IEEE 754 表示的,但是双精度浮点数表示的最大值对于 real*8 类型的变量来说似乎太大了(即如果我尝试分配 1.7976931348623157e+308 这样的变量 gfortran 抱怨)。 C 和 C++ 为此目的预定义了 constants/generic 函数,但我找不到 Fortran 等效函数。

注意:我知道 real*8 不是 真正 标准的一部分,但似乎没有其他方法可以可靠地指定浮点数应该使用双精度格式。

可能有更好的方法来检测溢出,但您的问题的准确答案是使用 huge 函数。 HUGE(a) returns 类型 a 可表示的最大可能数。

是这样的吗?

real(REAL64) function func( a, b )
  use, intrinsic :: iso_fortran_env, only: REAL64, INT64
  use, intrinsic :: ieee_arithmetic, only: ieee_value, ieee_set_flag, IEEE_OVERFLOW, IEEE_QUIET_NAN
  implicit none
  real(REAL64), intent(in) :: a, b
  real(REAL64), parameter  :: MAX64 = huge(0.0_REAL64)

  if ( b > MAX64-a ) then
    ! Set IEEE_OVERFLOW flag and return NaN
    call ieee_set_flag(IEEE_OVERFLOW,.true.)
    func = ieee_value(func,IEEE_QUIET_NAN)
  else
    func = a + b
  end if

  return
end function func

我能找到的内在 ieee_exceptions 模块是:
https://github.com/gcc-mirror/gcc/blob/master/libgfortran/ieee/ieee_exceptions.F90

有关设置 NaN 值的信息,请参阅