202 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
FUNCTION
 | 
						|
        <<strtoufix16>>, <<strtoufix32>>, <<strtoufix64>>---string to signed fixed point
 | 
						|
 | 
						|
INDEX
 | 
						|
	strtoufix16
 | 
						|
INDEX
 | 
						|
	strtoufix32
 | 
						|
INDEX
 | 
						|
	strtoufix64
 | 
						|
INDEX
 | 
						|
	_strtoufix16_r
 | 
						|
INDEX
 | 
						|
	_strtoufix32_r
 | 
						|
INDEX
 | 
						|
	_strtoufix64_r
 | 
						|
 | 
						|
ANSI_SYNOPSIS
 | 
						|
	#include <stdlib.h>
 | 
						|
        __uint16_t strtoufix16 (const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
        __uint32_t strtoufix32 (const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
        __uint64_t strtoufix64 (const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
        __uint16_t _strtoufix16_r (void *<[reent]>, 
 | 
						|
                       const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
        __uint32_t _strtoufix32_r (void *<[reent]>, 
 | 
						|
                       const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
        __uint64_t _strtoufix64_r (void *<[reent]>, 
 | 
						|
                       const char *<[s]>, char **<[ptr]>);
 | 
						|
 | 
						|
TRAD_SYNOPSIS
 | 
						|
	#include <stdlib.h>
 | 
						|
	__uint16_t strtoufix16 (<[s]>, <[ptr]>)
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
	__uint32_t strtoufix32 (<[s]>, <[ptr]>)
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
	__uint64_t strtoufix64 (<[s]>, <[ptr]>)
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
	__uint16_t _strtoufix16_r (<[reent]>, <[s]>, <[ptr]>)
 | 
						|
	char *<[reent]>;
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
	__uint32_t _strtoufix32_r (<[reent]>, <[s]>, <[ptr]>)
 | 
						|
	char *<[reent]>;
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
	__uint64_t _strtoufix64_r (<[reent]>, <[s]>, <[ptr]>)
 | 
						|
	char *<[reent]>;
 | 
						|
        char *<[s]>;
 | 
						|
        char **<[ptr]>;
 | 
						|
 | 
						|
DESCRIPTION
 | 
						|
        The function <<strtoufix16>> converts the string <<*<[s]>>> to
 | 
						|
	a fixed-point 16-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]>.
 | 
						|
 | 
						|
	<<strtoufix32>> is identical to <<strtoufix16>> except that it 
 | 
						|
	converts to fixed-point 32-bit fraction representation.
 | 
						|
	<<strtoufix64>> is also similar, except that it converts
 | 
						|
	to fixed-point 64-bit fraction.
 | 
						|
 | 
						|
	The alternate functions <<_strtoufix16_r>>, <<_strtoufix32_r>>,
 | 
						|
	and <<_strtoufix64_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 unsigned 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 0, then the output is saturated to 0
 | 
						|
	and <<ERANGE>> is stored in errno.  Otherwise, the converted value is returned in the
 | 
						|
	specified fixed-point format.
 | 
						|
 | 
						|
PORTABILITY
 | 
						|
        <<strtoufix16>>, <<strtoufix32>>, and <<strtoufix64>> 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 16-bit value.
 | 
						|
 *
 | 
						|
 * Ignores `locale' stuff.
 | 
						|
 */
 | 
						|
__uint16_t
 | 
						|
_DEFUN (_strtoufix16_r, (rptr, nptr, endptr),
 | 
						|
	struct _reent *rptr _AND
 | 
						|
	_CONST char *nptr _AND
 | 
						|
	char **endptr)
 | 
						|
{
 | 
						|
  union double_union dbl;
 | 
						|
  unsigned long tmp, tmp2, result;
 | 
						|
  int exp, negexp;
 | 
						|
 | 
						|
  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 0;
 | 
						|
      return USHRT_MAX;
 | 
						|
    }
 | 
						|
 | 
						|
  /* check for normal saturation */
 | 
						|
  if (dbl.d >= 1.0)
 | 
						|
    {
 | 
						|
      rptr->_errno = ERANGE;
 | 
						|
      return USHRT_MAX;
 | 
						|
    }
 | 
						|
  else if (dbl.d < 0)
 | 
						|
    {
 | 
						|
      rptr->_errno = ERANGE;
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
 | 
						|
  /* otherwise we have normal postive number in range */
 | 
						|
 | 
						|
  /* strip off exponent */
 | 
						|
  exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
 | 
						|
  negexp = -exp;
 | 
						|
  if (negexp > 16)
 | 
						|
    return 0;
 | 
						|
  /* add in implicit normalized bit */
 | 
						|
  tmp = word0(dbl) | Exp_msk1;
 | 
						|
  /* remove exponent and sign */
 | 
						|
  tmp <<= Ebits;
 | 
						|
  /* perform rounding */
 | 
						|
  tmp2 = tmp + (1 << (negexp + 14));
 | 
						|
  result = tmp2 >> (negexp + 15);
 | 
						|
  /* if rounding causes carry, must add carry bit in */
 | 
						|
  if (tmp2 < tmp)
 | 
						|
    {
 | 
						|
      if (negexp == 0)
 | 
						|
	{
 | 
						|
	  /* we have overflow which means saturation */
 | 
						|
	  rptr->_errno = ERANGE;
 | 
						|
	  return USHRT_MAX;
 | 
						|
	}
 | 
						|
      result |= (1 << (16 - negexp));
 | 
						|
    }
 | 
						|
 | 
						|
  return (__uint16_t)result;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef _REENT_ONLY
 | 
						|
 | 
						|
__uint16_t
 | 
						|
_DEFUN (strtoufix16, (s, ptr, base),
 | 
						|
	_CONST char *s _AND
 | 
						|
	char **ptr)
 | 
						|
{
 | 
						|
  return _strtoufix16_r (_REENT, s, ptr);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#endif /* __SPE__ */
 |