t2ex/bsd_source/lib/libc/src_bsd/math/s_nan.c | bare source | permlink (0.02 seconds) |
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 */