fiss

Friedel's Initialization and Service Supervision
Log | Files | Refs | LICENSE

nan64.c (1287B)


      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 
     16 static uvlong uvnan    = ((uvlong) 0x7FF00000 << 32) | 0x00000001;
     17 static uvlong uvinf    = ((uvlong) 0x7FF00000 << 32) | 0x00000000;
     18 static uvlong uvneginf = ((uvlong) 0xFFF00000 << 32) | 0x00000000;
     19 
     20 /* gcc sees through the obvious casts. */
     21 static uvlong
     22 d2u(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 
     32 static double
     33 u2d(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 
     43 double
     44 __NaN(void) {
     45 	return u2d(uvnan);
     46 }
     47 
     48 int __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 
     56 double
     57 __Inf(int sign) {
     58 	return u2d(sign < 0 ? uvneginf : uvinf);
     59 }
     60 
     61 int __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 }