gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/math/s_nan.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*      $OpenBSD: s_nan.c,v 1.7 2011/05/30 18:34:38 martynas Exp $   */
    2: /*-
    3:  * Copyright (c) 2007 David Schultz
    4:  * All rights reserved.
    5:  *
    6:  * Redistribution and use in source and binary forms, with or without
    7:  * modification, are permitted provided that the following conditions
    8:  * are met:
    9:  * 1. Redistributions of source code must retain the above copyright
   10:  *    notice, this list of conditions and the following disclaimer.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  *
   15:  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18:  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   19:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25:  * SUCH DAMAGE.
   26:  *
   27:  * $FreeBSD: src/lib/msun/src/s_nan.c,v 1.2 2007/12/18 23:46:32 das Exp $
   28:  */
   29: 
   30: /* LINTLIBRARY */
   31: 
   32: #include <sys/cdefs.h>
   33: #include <sys/types.h>
   34: #include <sys/endian.h>
   35: #include <ctype.h>
   36: #include <float.h>
   37: #include <math.h>
   38: #include <stdint.h>
   39: #include <strings.h>
   40: 
   41: #include "math_private.h"
   42: 
   43: /*
   44:  * OpenBSD's ctype doesn't have digittoint, so we define it here.
   45:  */
   46: static int
   47: _digittoint(int c)
   48: {
   49:         if (!isxdigit(c))
   50:                 return 0;
   51: 
   52:         if (isdigit(c))
   53:                 return c - '0';
   54:         else
   55:                 return isupper(c) ? c - 'A' + 10 : c - 'a' + 10;
   56: }
   57: 
   58: /*
   59:  * Scan a string of hexadecimal digits (the format nan(3) expects) and
   60:  * make a bit array (using the local endianness). We stop when we
   61:  * encounter an invalid character, NUL, etc.  If we overflow, we do
   62:  * the same as gcc's __builtin_nan(), namely, discard the high order bits.
   63:  *
   64:  * The format this routine accepts needs to be compatible with what is used
   65:  * in contrib/gdtoa/hexnan.c (for strtod/scanf) and what is used in
   66:  * __builtin_nan(). In fact, we're only 100% compatible for strings we
   67:  * consider valid, so we might be violating the C standard. But it's
   68:  * impossible to use nan(3) portably anyway, so this seems good enough.
   69:  */
   70: void
   71: _scan_nan(uint32_t *words, int num_words, const char *s)
   72: {
   73:         int si;                /* index into s */
   74:         int bitpos;    /* index into words (in bits) */
   75: 
   76:         bzero(words, num_words * sizeof(uint32_t));
   77: 
   78:         /* Allow a leading '0x'. (It's expected, but redundant.) */
   79:         if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
   80:                 s += 2;
   81: 
   82:         /* Scan forwards in the string, looking for the end of the sequence. */
   83:         for (si = 0; isxdigit(s[si]); si++)
   84:                 ;
   85: 
   86:         /* Scan backwards, filling in the bits in words[] as we go. */
   87: #if _BYTE_ORDER == _LITTLE_ENDIAN
   88:         for (bitpos = 0; bitpos < 32 * num_words; bitpos += 4) {
   89: #else
   90:         for (bitpos = 32 * num_words - 4; bitpos >= 0; bitpos -= 4) {
   91: #endif
   92:                 if (--si < 0)
   93:                         break;
   94:                 words[bitpos / 32] |= _digittoint(s[si]) << (bitpos % 32);
   95:         }
   96: }
   97: 
   98: double
   99: nan(const char *s)
  100: {
  101:         union {
  102:                 double d;
  103:                 uint32_t bits[2];
  104:         } u;
  105: 
  106:         _scan_nan(u.bits, 2, s);
  107: #if _BYTE_ORDER == _LITTLE_ENDIAN
  108:         u.bits[1] |= 0x7ff80000;
  109: #else
  110:         u.bits[0] |= 0x7ff80000;
  111: #endif
  112:         return (u.d);
  113: }
  114: 
  115: float
  116: nanf(const char *s)
  117: {
  118:         union {
  119:                 float f;
  120:                 uint32_t bits[1];
  121:         } u;
  122: 
  123:         _scan_nan(u.bits, 1, s);
  124:         u.bits[0] |= 0x7fc00000;
  125:         return (u.f);
  126: }
  127: 
  128: #if     LDBL_MANT_DIG == 53
  129: #ifdef  lint
  130: /* PROTOLIB1 */
  131: long double nanl(const char *);
  132: #else   /* lint */
  133: __weak_alias(nanl, nan);
  134: #endif  /* lint */
  135: #endif  /* LDBL_MANT_DIG == 53 */