9base

revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log | Files | Refs | README | LICENSE

nan64.c (1196B)


      1 /*
      2  * 64-bit IEEE not-a-number routines.
      3  * This is big/little-endian portable assuming that 
      4  * the 64-bit doubles and 64-bit integers have the
      5  * same byte ordering.
      6  */
      7 
      8 #include "plan9.h"
      9 #include <assert.h>
     10 #include "fmt.h"
     11 #include "fmtdef.h"
     12 
     13 static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
     14 static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
     15 static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
     16 
     17 /* gcc sees through the obvious casts. */
     18 static uvlong
     19 d2u(double d)
     20 {
     21 	union {
     22 		uvlong v;
     23 		double d;
     24 	} u;
     25 	assert(sizeof(u.d) == sizeof(u.v));
     26 	u.d = d;
     27 	return u.v;
     28 }
     29 
     30 static double
     31 u2d(uvlong v)
     32 {
     33 	union {
     34 		uvlong v;
     35 		double d;
     36 	} u;
     37 	assert(sizeof(u.d) == sizeof(u.v));
     38 	u.v = v;
     39 	return u.d;
     40 }
     41 
     42 double
     43 __NaN(void)
     44 {
     45 	return u2d(uvnan);
     46 }
     47 
     48 int
     49 __isNaN(double d)
     50 {
     51 	uvlong x;
     52 	
     53 	x = d2u(d);
     54 	/* IEEE 754: exponent bits 0x7FF and non-zero mantissa */
     55 	return (x&uvinf) == uvinf && (x&~uvneginf) != 0;
     56 }
     57 
     58 double
     59 __Inf(int sign)
     60 {
     61 	return u2d(sign < 0 ? uvneginf : uvinf);
     62 }
     63 
     64 int
     65 __isInf(double d, int sign)
     66 {
     67 	uvlong x;
     68 	
     69 	x = d2u(d);
     70 	if(sign == 0)
     71 		return x==uvinf || x==uvneginf;
     72 	else if(sign > 0)
     73 		return x==uvinf;
     74 	else
     75 		return x==uvneginf;
     76 }