nan64.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }