------- Comment #5 from jkrahn at nc dot rr dot com 2007-03-16 03:46 ------- BOZ processing was recently broken in gfortran. I assume it relates to the issues here.
The current problem is shown in this bit of code: write(*,*)'NaN(8)=',real(z'FFF8000000000000',8) end gfortran, even with -std=f2003, claims that the BOZ data is too big. Apparently, it is first converting to an UNSIGNED integer, then trying to cast to a SIGNED Fortran integer. With F2003, this form of BOZ should do a 'reinterpret-cast' of raw binary bits directly to the destination type. 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) Again, it is being intepreted as an UNSIGNED int then static-cast to a signed in, thus overflowing. The traditional behavior is for all BOZ to be initially interpreted as the largets integer type supported. As usual with Fortran, that is a horrible definition. In order to define a -1 BYTE, you have to write out the whole 8-bytes worth of FF. Intel seems to use a sane (but nonstandard) method that appears to interpret initially as the smallest type that contains all of the bits specified. F95 dropped BOZ because of the lame definition, but F2003 brought it back for use mainly within REAL() and INT(), which allow the raw initial interpretation in a sensible way. 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. In any case, it comes down to a raw binary value converted directly to the destination for the F2003 forms. For the older form, which is still the case in F2003 for DATA statements, it is hard to know whether to 'cheat' and allow z'FF' to define a -1 byte, or stick to the strict messed-up definition. What did G77 do? 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.) 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. What we really need is a NAN(kind=8) intrinsic. -- jkrahn at nc dot rr dot com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jkrahn at nc dot rr dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29471