Skip to content

0.65/AIX

2 messages · Thomas J Vogels, Peter Dalgaard

#
"Peter" == Peter Dalgaard BSA <p.dalgaard@biostat.ku.dk> writes:

Peter> Something pretty close to the following should work:
Peter> 
Peter> #define R_FINITE(x) ({double y = x; \
Peter> *((int *) &y) & 0x7ff00000 != 0x7ff00000})
Peter> 
Peter> #define ISNAN(x) ({double y = x; \
Peter> *((int *) &y) & 0x7ff00000 == 0x7ff00000 && \
Peter> (*((int *) &y) & 0x7fffffff != 0x7ff00000 || *((int *) &y + 1) != 0)}

Pretty but not close ;-)  Sorry, but I can't compile these macros.  I
see your point for the local var, but cc and gcc choke on it.

I've looked into /usr/include/fp.h which is included for AIX
platforms.  (Its version is 1.9)  There are defines for FINITE,
IS_INF, IS_NAN.  Can we use them?  Roll our own finite()?
Does it make sense for configure to check, not only whether finite
exists but also whether it's broken?

BTW, if you step thru EncodeReal you see that !R_FINITE(x) if false
for 1/0 (i.e. 1/0 is not detected as not finite).

Here is first the C code to show what's working what's not.  (I picked
your stuff and added the calls to the macros.)  This is followed by
the output when compiled with cc and gcc.  I'm having major headaches
here with the -D_XOPEN_SOURCE_EXTENDED (details follow).  Maybe we can
dump finite in favor of FINITE?

Are  my assumptions about the return values are correct?

---> isfinite.c <---
#include <stdio.h>
#include <math.h>

#ifdef _AIX
# include <fp.h>
#endif

main() {
  double x,x2,x3;
  printf("finite(1.0)= %d (=1, hopefully)\n", finite(1.0));
  x=1./0.; x2= (-1.)/0.;  x3 = 0./0.;
  printf("Inf := 1/0 = %f;\t -Inf := -1/0 = %f;\t NaN:= 0/0 = %f\n",x,
         x2, x3);
  printf("finite(x), f.(x2), f.(x3): %d %d %d  (should all be 0)\n",
         finite(x),finite(x2),finite(x3));
  printf("Now the `bits':\n");
  printf(" Inf : %0x,%0x\n", ((int *) &x )[0], ((int *) &x )[1]);
  printf("-Inf : %0x,%0x\n", ((int *) &x2)[0], ((int *) &x2)[1]);
  printf(" NaN : %0x,%0x\n", ((int *) &x3)[0], ((int *) &x3)[1]);

#ifdef _AIX
  printf("FINITE(x), f.(x2), f.(x3): %d %d %d  (should all be 0)\n",
         FINITE(x),FINITE(x2),FINITE(x3));
  printf("IS_NAN(x), f.(x2), f.(x3): %d %d %d  (should be 0 0 1)\n",
         IS_NAN(x),IS_NAN(x2),IS_NAN(x3));
  printf("IS_INF(x), f.(x2), f.(x3): %d %d %d  (should be 1 1 0)\n",
         IS_INF(x),IS_INF(x2),IS_INF(x3));
#endif
}
---> end of isfinite.c <---

---> output <--
r-devel $ cc isfinite.c -o isfinite 2>/dev/null && ./isfinite
finite(1.0)= 1 (=1, hopefully)
Inf := 1/0 = INF;        -Inf := -1/0 = -INF;    NaN:= 0/0 = NaNQ
finite(x), f.(x2), f.(x3): 0 0 0  (should all be 0)
Now the `bits':
 Inf : 7ff00000,0
-Inf : fff00000,0
 NaN : 7ff80000,0
FINITE(x), f.(x2), f.(x3): 0 0 0  (should all be 0)
IS_NAN(x), f.(x2), f.(x3): 0 0 1  (should be 0 0 1)
IS_INF(x), f.(x2), f.(x3): 1 1 0  (should be 1 1 0)
r-devel $ gcc -g -O2 isfinite.c -o isfinite 2>/dev/null && ./isfinite
finite(1.0)= 1 (=1, hopefully)
Inf := 1/0 = INF;        -Inf := -1/0 = -INF;    NaN:= 0/0 = NaNQ
finite(x), f.(x2), f.(x3): 1 1 1  (should all be 0)
Now the `bits':
 Inf : 7ff00000,0
-Inf : fff00000,0
 NaN : 7fffffff,ffffffff
FINITE(x), f.(x2), f.(x3): 0 0 0  (should all be 0)
IS_NAN(x), f.(x2), f.(x3): 0 0 1  (should be 0 0 1)
IS_INF(x), f.(x2), f.(x3): 1 1 0  (should be 1 1 0)
r-devel $ gcc -g -O2 isfinite.c -o isfinite -D_XOPEN_SOURCE_EXTENDED=1
2>/dev/null && ./isfinite
finite(1.0)= 1 (=1, hopefully)
Inf := 1/0 = INF;        -Inf := -1/0 = -INF;    NaN:= 0/0 = NaNQ
finite(x), f.(x2), f.(x3): 0 0 0  (should all be 0)
Now the `bits':
 Inf : 7ff00000,0
-Inf : fff00000,0
 NaN : 7fffffff,ffffffff
FINITE(x), f.(x2), f.(x3): 0 0 0  (should all be 0)
IS_NAN(x), f.(x2), f.(x3): 0 0 1  (should be 0 0 1)
IS_INF(x), f.(x2), f.(x3): 1 1 0  (should be 1 1 0)

--
mailto:tov@ece.cmu.edu (Tom Vogels)   Tel: (412) 268-6638   FAX: -3204

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Thomas Vogels <tov@infiniti.ece.cmu.edu> writes:
I take it that you fixed the missing ')' in ISNAN? Too bad. Perhaps it
can work without the local "y"? I put it in just to catch cases where
x might be in a register so that you cannot take its address.
That would make very good sense. The code would probably have to go in
an "#if aix" type clause, but so would my suggestion.
It certainly would.
Yes. If you look at R_FINITE, you'll see that the logic is
essentially: If HAVE_FINITE use finite() else assume non-IEEE and only
check for the internal NA code. So if either finite() misbehaves or
doesn't exist, that will happen.
They look fine. Would seem that only gcc without the -D_XOPENetc is
having trouble with finite() -- why? could that be a gcc bug?

What happens with isnan(), is that as buggy as finite()?

It looks quite feasible simply to put

#ifdef _AIX
	#define R_FINITE(x) FINITE(X)
	#define R_ISNAN(x)  IS_NAN(X)
#endif

or something like it in Arith.h