------- 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