Cygwin: Add new APIs tc[gs]etwinsize()
[newlib-cygwin.git] / newlib / libc / machine / powerpc / strtoufix16.c
blob415652dd2e78a64a96e5e84c16e4d4630f5127ca
1 /*
2 FUNCTION
3 <<strtoufix16>>, <<strtoufix32>>, <<strtoufix64>>---string to signed fixed point
5 INDEX
6 strtoufix16
7 INDEX
8 strtoufix32
9 INDEX
10 strtoufix64
11 INDEX
12 _strtoufix16_r
13 INDEX
14 _strtoufix32_r
15 INDEX
16 _strtoufix64_r
18 SYNOPSIS
19 #include <stdlib.h>
20 __uint16_t strtoufix16 (const char *<[s]>, char **<[ptr]>);
22 __uint32_t strtoufix32 (const char *<[s]>, char **<[ptr]>);
24 __uint64_t strtoufix64 (const char *<[s]>, char **<[ptr]>);
26 __uint16_t _strtoufix16_r (void *<[reent]>,
27 const char *<[s]>, char **<[ptr]>);
29 __uint32_t _strtoufix32_r (void *<[reent]>,
30 const char *<[s]>, char **<[ptr]>);
32 __uint64_t _strtoufix64_r (void *<[reent]>,
33 const char *<[s]>, char **<[ptr]>);
35 DESCRIPTION
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>>.
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]>.
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.
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.
63 RETURNS
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.
73 PORTABILITY
74 <<strtoufix16>>, <<strtoufix32>>, and <<strtoufix64>> are non-standard.
76 The OS subroutines of <<strtod>> are required.
79 #ifdef __SPE__
81 #include <_ansi.h>
82 #include <limits.h>
83 #include <errno.h>
84 #include <stdlib.h>
85 #include <reent.h>
86 #include "vfieeefp.h"
89 * Convert a string to a fixed-point 16-bit value.
91 * Ignores `locale' stuff.
93 __uint16_t
94 _strtoufix16_r (struct _reent *rptr,
95 const char *nptr,
96 char **endptr)
98 union double_union dbl;
99 unsigned long tmp, tmp2, result;
100 int exp, negexp;
102 dbl.d = _strtod_r (rptr, nptr, endptr);
104 /* treat NAN as domain error, +/- infinity as saturation */
105 if (!finite(dbl.d))
107 if (isnan (dbl.d))
109 _REENT_ERRNO(rptr) = EDOM;
110 return 0;
112 _REENT_ERRNO(rptr) = ERANGE;
113 if (word0(dbl) & Sign_bit)
114 return 0;
115 return USHRT_MAX;
118 /* check for normal saturation */
119 if (dbl.d >= 1.0)
121 _REENT_ERRNO(rptr) = ERANGE;
122 return USHRT_MAX;
124 else if (dbl.d < 0)
126 _REENT_ERRNO(rptr) = ERANGE;
127 return 0;
130 /* otherwise we have normal postive number in range */
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)
147 if (negexp == 0)
149 /* we have overflow which means saturation */
150 _REENT_ERRNO(rptr) = ERANGE;
151 return USHRT_MAX;
153 result |= (1 << (16 - negexp));
156 return (__uint16_t)result;
159 #ifndef _REENT_ONLY
161 __uint16_t
162 strtoufix16 (const char *s,
163 char **ptr)
165 return _strtoufix16_r (_REENT, s, ptr);
168 #endif
170 #endif /* __SPE__ */