123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #include <ctype.h>
- #include <float.h>
- #include <openlibm_math.h>
- #include <stdint.h>
- #include <string.h> //for memset
- #include "math_private.h"
- #if !defined(__APPLE__) && !defined(__FreeBSD__)
- static __inline int digittoint(int c) {
- if ('0' <= c && c <= '9')
- return (c - '0');
- else if ('A' <= c && c <= 'F')
- return (c - 'A' + 10);
- else if ('a' <= c && c <= 'f')
- return (c - 'a' + 10);
- return 0;
- }
- #endif
- OLM_DLLEXPORT void
- __scan_nan(u_int32_t *words, int num_words, const char *s)
- {
- int si;
- int bitpos;
- memset(words, 0, num_words * sizeof(u_int32_t));
-
- if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
- s += 2;
-
- for (si = 0; isxdigit(s[si]); si++)
- ;
-
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- for (bitpos = 0; bitpos < 32 * num_words; bitpos += 4) {
- #else
- for (bitpos = 32 * num_words - 4; bitpos >= 0; bitpos -= 4) {
- #endif
- if (--si < 0)
- break;
- words[bitpos / 32] |= digittoint(s[si]) << (bitpos % 32);
- }
- }
- OLM_DLLEXPORT double
- nan(const char *s)
- {
- union {
- double d;
- u_int32_t bits[2];
- } u;
- __scan_nan(u.bits, 2, s);
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- u.bits[1] |= 0x7ff80000;
- #else
- u.bits[0] |= 0x7ff80000;
- #endif
- return (u.d);
- }
- OLM_DLLEXPORT float
- nanf(const char *s)
- {
- union {
- float f;
- u_int32_t bits[1];
- } u;
- __scan_nan(u.bits, 1, s);
- u.bits[0] |= 0x7fc00000;
- return (u.f);
- }
- #if (LDBL_MANT_DIG == 53)
- __weak_reference(nan, nanl);
- #endif
|