URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-stable/] [newlib-1.18.0/] [newlib/] [libc/] [machine/] [powerpc/] [strtosfix16.c] - Rev 816
Go to most recent revision | Compare with Previous | Blame | View Log
/* FUNCTION <<strtosfix16>>, <<strtosfix32>>, <<strtosfix64>>---string to signed fixed point INDEX strtosfix16 INDEX strtosfix32 INDEX strtosfix64 INDEX _strtosfix16_r INDEX _strtosfix32_r INDEX _strtosfix64_r ANSI_SYNOPSIS #include <stdlib.h> __int16 strtosfix16 (const char *<[s]>, char **<[ptr]>); __int32 strtosfix32 (const char *<[s]>, char **<[ptr]>); __int64 strtosfix64 (const char *<[s]>, char **<[ptr]>); __int16 _strtosfix16_r (void *<[reent]>, const char *<[s]>, char **<[ptr]>); __int32 _strtosfix32_r (void *<[reent]>, const char *<[s]>, char **<[ptr]>); __int64 _strtosfix64_r (void *<[reent]>, const char *<[s]>, char **<[ptr]>); TRAD_SYNOPSIS #include <stdlib.h> __int16 strtosfix16 (<[s]>, <[ptr]>) char *<[s]>; char **<[ptr]>; __int32 strtosfix32 (<[s]>, <[ptr]>) char *<[s]>; char **<[ptr]>; __int64 strtosfix64 (<[s]>, <[ptr]>) char *<[s]>; char **<[ptr]>; __int16 _strtosfix16_r (<[reent]>, <[s]>, <[ptr]>) char *<[reent]>; char *<[s]>; char **<[ptr]>; __int32 _strtosfix32_r (<[reent]>, <[s]>, <[ptr]>) char *<[reent]>; char *<[s]>; char **<[ptr]>; __int64 _strtosfix64_r (<[reent]>, <[s]>, <[ptr]>) char *<[reent]>; char *<[s]>; char **<[ptr]>; DESCRIPTION The function <<strtosfix16>> converts the string <<*<[s]>>> to a fixed-point sign + 15-bits fraction representation. The function follows the same rules as <<strtod>>. The substring converted is the longest initial subsequence of <[s]>, beginning with the first non-whitespace character, that has the format: .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] The substring contains no characters if <[s]> is empty, consists entirely of whitespace, or if the first non-whitespace character is something other than <<+>>, <<->>, <<.>>, or a digit. If the substring is empty, no conversion is done, and the value of <[s]> is stored in <<*<[ptr]>>>. Otherwise, the substring is converted, and a pointer to the final string (which will contain at least the terminating null character of <[s]>) is stored in <<*<[ptr]>>>. If you want no assignment to <<*<[ptr]>>>, pass a null pointer as <[ptr]>. <<strtosfix32>> is identical to <<strtosfix16>> except that it converts to fixed-point sign + 31-bits fraction representation. <<strtosfix64>> is also similar, except that it converts to fixed-point sign + 63-bit fraction format. The alternate functions <<_strtosfix16_r>>, <<_strtosfix32_r>>, and <<_strtosfix64_r>> are reentrant versions. The extra argument <[reent]> is a pointer to a reentrancy structure. RETURNS The functions return the converted substring value, if any. If no conversion can be performed, then 0 is returned. If the converted value is a NaN, 0 is returned and errno is set to <<EDOM>>. If the converted value exceeds the maximum positive fixed-point value, the output value is saturated to the maximum value and <<ERANGE>> is stored in errno. If the converted value is less than the minimum fixed-point negative value, then the output is saturated to the minimum value and <<ERANGE>> is stored in errno. Otherwise, the converted value is returned in the specified fixed-point format. PORTABILITY <<strtosfix16>>, <<strtosfix32>>, and <<strtosfix64>> are non-standard. The OS subroutines of <<strtod>> are required. */ #ifdef __SPE__ #include <_ansi.h> #include <limits.h> #include <errno.h> #include <stdlib.h> #include <reent.h> #include "vfieeefp.h" /* * Convert a string to a fixed-point (sign + 15-bits) value. * * Ignores `locale' stuff. */ __int16_t _DEFUN (_strtosfix16_r, (rptr, nptr, endptr), struct _reent *rptr _AND _CONST char *nptr _AND char **endptr) { union double_union dbl; unsigned long tmp, tmp2; int exp, negexp, sign; __int16_t result; dbl.d = _strtod_r (rptr, nptr, endptr); /* treat NAN as domain error, +/- infinity as saturation */ if (!finite(dbl.d)) { if (isnan (dbl.d)) { rptr->_errno = EDOM; return 0; } rptr->_errno = ERANGE; if (word0(dbl) & Sign_bit) return SHRT_MIN; return SHRT_MAX; } /* check for normal saturation */ if (dbl.d >= 1.0) { rptr->_errno = ERANGE; return SHRT_MAX; } else if (dbl.d < -1.0) { rptr->_errno = ERANGE; return SHRT_MIN; } /* otherwise we have normal number in range */ /* strip off sign and exponent */ sign = word0(dbl) & Sign_bit; exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias; negexp = -exp; if (negexp > 15) return 0; /* add in implicit normalized bit */ tmp = word0(dbl) | Exp_msk1; /* remove exponent and sign */ tmp <<= Ebits; if (negexp != 0) { /* perform rounding */ tmp2 = tmp + (1 << (negexp - 1)); result = (short)(tmp2 >> (negexp + 16)); /* check if rounding caused carry bit which must be added into result */ if (tmp2 < tmp) result |= (1 << (16 - negexp)); /* check if positive saturation has occurred because of rounding */ if (!sign && result < 0) { rptr->_errno = ERANGE; return SHRT_MAX; } } else { /* we have -1.0, no rounding necessary */ return SHRT_MIN; } return sign ? -result : result; } #ifndef _REENT_ONLY __int16_t _DEFUN (strtosfix16, (s, ptr, base), _CONST char *s _AND char **ptr) { return _strtosfix16_r (_REENT, s, ptr); } #endif #endif /* __SPE__ */
Go to most recent revision | Compare with Previous | Blame | View Log