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 }