unix/fiss

lib/libfmt/nan64.c in master
Repositories | Summary | Log | Files | LICENSE

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}