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