github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/src/lib9/fmt/nan64.c (about)

     1  /*
     2   * The authors of this software are Rob Pike and Ken Thompson,
     3   * with contributions from Mike Burrows and Sean Dorward.
     4   *
     5   *     Copyright (c) 2002-2006 by Lucent Technologies.
     6   *     Portions Copyright (c) 2004 Google Inc.
     7   * 
     8   * Permission to use, copy, modify, and distribute this software for any
     9   * purpose without fee is hereby granted, provided that this entire notice
    10   * is included in all copies of any software which is or includes a copy
    11   * or modification of this software and in all copies of the supporting
    12   * documentation for such software.
    13   * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
    14   * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES 
    15   * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING 
    16   * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
    17   */
    18  
    19  /*
    20   * 64-bit IEEE not-a-number routines.
    21   * This is big/little-endian portable assuming that
    22   * the 64-bit doubles and 64-bit integers have the
    23   * same byte ordering.
    24   */
    25  
    26  #include <u.h>
    27  #include <libc.h>
    28  #include "fmtdef.h"
    29  
    30  static uvlong uvnan    = ((uvlong)0x7FF00000<<32)|0x00000001;
    31  static uvlong uvinf    = ((uvlong)0x7FF00000<<32)|0x00000000;
    32  static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000;
    33  
    34  /* gcc sees through the obvious casts. */
    35  static uvlong
    36  d2u(double d)
    37  {
    38  	union {
    39  		uvlong v;
    40  		double d;
    41  	} u;
    42  	assert(sizeof(u.d) == sizeof(u.v));
    43  	u.d = d;
    44  	return u.v;
    45  }
    46  
    47  static double
    48  u2d(uvlong v)
    49  {
    50  	union {
    51  		uvlong v;
    52  		double d;
    53  	} u;
    54  	assert(sizeof(u.d) == sizeof(u.v));
    55  	u.v = v;
    56  	return u.d;
    57  }
    58  
    59  double
    60  __NaN(void)
    61  {
    62  	return u2d(uvnan);
    63  }
    64  
    65  int
    66  __isNaN(double d)
    67  {
    68  	uvlong x;
    69  
    70  	x = d2u(d);
    71  	/* IEEE 754: exponent bits 0x7FF and non-zero mantissa */
    72  	return (x&uvinf) == uvinf && (x&~uvneginf) != 0;
    73  }
    74  
    75  double
    76  __Inf(int sign)
    77  {
    78  	return u2d(sign < 0 ? uvneginf : uvinf);
    79  }
    80  
    81  int
    82  __isInf(double d, int sign)
    83  {
    84  	uvlong x;
    85  
    86  	x = d2u(d);
    87  	if(sign == 0)
    88  		return x==uvinf || x==uvneginf;
    89  	else if(sign > 0)
    90  		return x==uvinf;
    91  	else
    92  		return x==uvneginf;
    93  }