source: trunk/libs/newlib/src/newlib/libc/machine/powerpc/strtoufix16.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 4.5 KB
Line 
1/*
2FUNCTION
3        <<strtoufix16>>, <<strtoufix32>>, <<strtoufix64>>---string to signed fixed point
4
5INDEX
6        strtoufix16
7INDEX
8        strtoufix32
9INDEX
10        strtoufix64
11INDEX
12        _strtoufix16_r
13INDEX
14        _strtoufix32_r
15INDEX
16        _strtoufix64_r
17
18SYNOPSIS
19        #include <stdlib.h>
20        __uint16_t strtoufix16 (const char *<[s]>, char **<[ptr]>);
21
22        __uint32_t strtoufix32 (const char *<[s]>, char **<[ptr]>);
23
24        __uint64_t strtoufix64 (const char *<[s]>, char **<[ptr]>);
25
26        __uint16_t _strtoufix16_r (void *<[reent]>,
27                       const char *<[s]>, char **<[ptr]>);
28
29        __uint32_t _strtoufix32_r (void *<[reent]>,
30                       const char *<[s]>, char **<[ptr]>);
31
32        __uint64_t _strtoufix64_r (void *<[reent]>,
33                       const char *<[s]>, char **<[ptr]>);
34
35DESCRIPTION
36        The function <<strtoufix16>> converts the string <<*<[s]>>> to
37        a fixed-point 16-bits fraction representation.  The function
38        follows the same rules as <<strtod>>.
39
40        The substring converted is the longest initial
41        subsequence of <[s]>, beginning with the first
42        non-whitespace character, that has the format:
43        .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
44        The substring contains no characters if <[s]> is empty, consists
45        entirely of whitespace, or if the first non-whitespace
46        character is something other than <<+>>, <<->>, <<.>>, or a
47        digit. If the substring is empty, no conversion is done, and
48        the value of <[s]> is stored in <<*<[ptr]>>>.  Otherwise,
49        the substring is converted, and a pointer to the final string
50        (which will contain at least the terminating null character of
51        <[s]>) is stored in <<*<[ptr]>>>.  If you want no
52        assignment to <<*<[ptr]>>>, pass a null pointer as <[ptr]>.
53
54        <<strtoufix32>> is identical to <<strtoufix16>> except that it
55        converts to fixed-point 32-bit fraction representation.
56        <<strtoufix64>> is also similar, except that it converts
57        to fixed-point 64-bit fraction.
58
59        The alternate functions <<_strtoufix16_r>>, <<_strtoufix32_r>>,
60        and <<_strtoufix64_r>> are reentrant versions.
61        The extra argument <[reent]> is a pointer to a reentrancy structure.
62
63RETURNS
64        The functions return the converted substring value, if any.  If
65        no conversion can be performed, then 0 is returned.  If the converted
66        value is a NaN, 0 is returned and errno is set to <<EDOM>>.
67        If the converted value exceeds the maximum positive unsigned fixed-point value,
68        the output value is saturated to the maximum value and <<ERANGE>> is stored in
69        errno.  If the converted value is less than 0, then the output is saturated to 0
70        and <<ERANGE>> is stored in errno.  Otherwise, the converted value is returned in the
71        specified fixed-point format.
72
73PORTABILITY
74        <<strtoufix16>>, <<strtoufix32>>, and <<strtoufix64>> are non-standard.
75
76        The OS subroutines of <<strtod>> are required.
77*/
78
79#ifdef __SPE__
80
81#include <_ansi.h>
82#include <limits.h>
83#include <errno.h>
84#include <stdlib.h>
85#include <reent.h>
86#include "vfieeefp.h"
87
88/*
89 * Convert a string to a fixed-point 16-bit value.
90 *
91 * Ignores `locale' stuff.
92 */
93__uint16_t
94_strtoufix16_r (struct _reent *rptr,
95        const char *nptr,
96        char **endptr)
97{
98  union double_union dbl;
99  unsigned long tmp, tmp2, result;
100  int exp, negexp;
101
102  dbl.d = _strtod_r (rptr, nptr, endptr);
103
104  /* treat NAN as domain error, +/- infinity as saturation */
105  if (!finite(dbl.d))
106    {
107      if (isnan (dbl.d))
108        {
109          rptr->_errno = EDOM;
110          return 0;
111        }
112      rptr->_errno = ERANGE;
113      if (word0(dbl) & Sign_bit)
114        return 0;
115      return USHRT_MAX;
116    }
117
118  /* check for normal saturation */
119  if (dbl.d >= 1.0)
120    {
121      rptr->_errno = ERANGE;
122      return USHRT_MAX;
123    }
124  else if (dbl.d < 0)
125    {
126      rptr->_errno = ERANGE;
127      return 0;
128    }
129
130  /* otherwise we have normal postive number in range */
131
132  /* strip off exponent */
133  exp = ((word0(dbl) & Exp_mask) >> Exp_shift) - Bias;
134  negexp = -exp;
135  if (negexp > 16)
136    return 0;
137  /* add in implicit normalized bit */
138  tmp = word0(dbl) | Exp_msk1;
139  /* remove exponent and sign */
140  tmp <<= Ebits;
141  /* perform rounding */
142  tmp2 = tmp + (1 << (negexp + 14));
143  result = tmp2 >> (negexp + 15);
144  /* if rounding causes carry, must add carry bit in */
145  if (tmp2 < tmp)
146    {
147      if (negexp == 0)
148        {
149          /* we have overflow which means saturation */
150          rptr->_errno = ERANGE;
151          return USHRT_MAX;
152        }
153      result |= (1 << (16 - negexp));
154    }
155
156  return (__uint16_t)result;
157}
158
159#ifndef _REENT_ONLY
160
161__uint16_t
162strtoufix16 (const char *s,
163        char **ptr)
164{
165  return _strtoufix16_r (_REENT, s, ptr);
166}
167
168#endif
169
170#endif /* __SPE__ */
Note: See TracBrowser for help on using the repository browser.