------- Comment #9 from burnus at gcc dot gnu dot org  2007-03-16 09:45 -------
> The current problem is shown in this bit of code:
>   write(*,*)'NaN(8)=',real(z'FFF8000000000000',8)
>   end

Note: gfortran does not support Fortran 2003 BOZ yet.

> gfortran, even with -std=f2003, claims that the BOZ data is too big.
Use -fno-range-check to disable this checking. But this will still the old BOZ
extension and not the Fortran 2003 BOZ.

> Even without the reinterpret cast problem, integer BOZ is not handled
> correctly. This expression also claims the BOZ is too large:
>    int(z'FFFFFFFFFFFFFFFF',8)

The number is does not fit into -huge(1_8) ... huge(1_8) and is therefore
outside of the Fortran standard. -> -fno-range-check

> The traditional behavior is for all BOZ to be initially interpreted as the
> largets integer type supported.

Which is why gfortran gives no error if you use int(BOZ, kind=16).

> The only hassle with "processor dependent" definitions is that the result of a
> given binary value depends on a processor's internal binary format. So, IEEE
> floats are portable, but other long/quad real numbers are not.
"Processor dependent" in the Fortran language does not only mean the CPU but
also the compiler; nonetheless, in this regard most (all?) compilers produce
the same result on a given platform.

> A related problem is that I am trying to create a NaN constant (parameter). I
> can't use REAL+BOZ, but I also cannot define "real :: NaN = 0.0/0.0". In this
> case, divide-by-zero is invalid math, but should only be a warning and not an
> error. (I am speaking practically; I don't know what the standards say.)

The standard does not say anything about non-Fortran numbers. Fortran 2003 has
now support of the IEEE arithmetics, which allows NaN, denormalized numbers and
+/-INF, overflowing etc.

Thus for a Fortran 95 compiler, the 0./0. can always be rejected, whereas for
Fortran 2003 it is a bit unclearer (cf. below for a standard way to get Nan).

my personal trick is to use:
 real :: r, NaN
 r = 0.0
 NaN = 0.0/r
which does the NaN at run time. (You still need to have the right compiler
flags as otherwise you get an arithmetic exception at run time.)

> But, good news, I just discovered that this hack works:
>   NaN = transfer(ishft(int(z'FFF80000',8),32),0.0_8)
> I tried that a while back with gfortran and it crashed.

A modified version still crashes with gfortran:
  real(kind(0d0)) :: NaN = transfer(ishft(int(z'FFF80000',8),32),0d0)
  print *, NaN
Interestingly, this produces "0.0" with ifort, while g95 and sunf95 give "NaN".
See PR 31194.

> What we really need is a NAN(kind=8) intrinsic.

Well, one can do in Fortran 2003:
 use,intrinsic :: ieee_arithmetic
 real :: NaN
 NaN = ieee_value(x,ieee_quiet_nan)

(Note: IEEE arithmetic is not yet supported by many compilers, especially
gfortran does not support it yet.)

(In reply to comment #6)
> My vote is to just ignore the standards when it
> comes to negative BOZ, the way Intel has done it, which I HOPE is what F2008
> says.

Sorry, I think most people would like to have a standard conform compiler; we
cannot do so.

Besides IEEE arithmetic allows what you want. Using transfer is a non-portable
way to do so, which assumes a certain internal structure. And using your
integer BOZ are supported with -fno-range-check.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29471

Reply via email to