|
0
|
1 #ifndef CYGONCE_LIBC_STDLIB_INL |
|
|
2 #define CYGONCE_LIBC_STDLIB_INL |
|
|
3 //=========================================================================== |
|
|
4 // |
|
|
5 // stdlib.inl |
|
|
6 // |
|
|
7 // Inline implementations for the ANSI standard utility functions |
|
|
8 // defined in section 7.10 of the standard |
|
|
9 // |
|
|
10 //=========================================================================== |
|
|
11 //####COPYRIGHTBEGIN#### |
|
|
12 // |
|
|
13 // ------------------------------------------- |
|
|
14 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
15 // Version 1.0 (the "License"); you may not use this file except in |
|
|
16 // compliance with the License. You may obtain a copy of the License at |
|
|
17 // http://sourceware.cygnus.com/ecos |
|
|
18 // |
|
|
19 // Software distributed under the License is distributed on an "AS IS" |
|
|
20 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
21 // License for the specific language governing rights and limitations under |
|
|
22 // the License. |
|
|
23 // |
|
|
24 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
25 // September 30, 1998. |
|
|
26 // |
|
|
27 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
2
|
28 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
|
0
|
29 // ------------------------------------------- |
|
|
30 // |
|
|
31 //####COPYRIGHTEND#### |
|
|
32 //=========================================================================== |
|
|
33 //#####DESCRIPTIONBEGIN#### |
|
|
34 // |
|
2
|
35 // Author(s): jlarmour |
|
|
36 // Contributors: jlarmour@ |
|
|
37 // Date: 1999-03-02 |
|
0
|
38 // Purpose: |
|
|
39 // Description: |
|
2
|
40 // Usage: Do not include this file directly - include <stdlib.h> instead |
|
0
|
41 // |
|
|
42 //####DESCRIPTIONEND#### |
|
|
43 // |
|
|
44 //=========================================================================== |
|
|
45 |
|
|
46 // CONFIGURATION |
|
|
47 |
|
|
48 #include <pkgconf/libc.h> // Configuration header |
|
|
49 |
|
|
50 // INCLUDES |
|
|
51 |
|
2
|
52 #include <stddef.h> // NULL, wchar_t and size_t from compiler |
|
|
53 #include <stdlib.h> // Header for this file, just in case |
|
|
54 #include <cyg/infra/cyg_ass.h> // Assertion support |
|
|
55 #include <cyg/infra/cyg_trac.h> // Tracing support |
|
0
|
56 |
|
|
57 // FUNCTIONS |
|
|
58 |
|
|
59 //=========================================================================== |
|
|
60 |
|
|
61 // 7.10.1 String conversion functions |
|
|
62 |
|
|
63 |
|
|
64 CYGPRI_LIBC_INLINE double |
|
|
65 atof( const char *nptr ) |
|
|
66 { |
|
|
67 return strtod( nptr, (char **)NULL ); |
|
|
68 } // atof() |
|
|
69 |
|
|
70 CYGPRI_LIBC_INLINE int |
|
|
71 atoi( const char *nptr ) |
|
|
72 { |
|
|
73 return (int)strtol( nptr, (char **)NULL, 10 ); |
|
|
74 } // atoi() |
|
|
75 |
|
|
76 |
|
|
77 CYGPRI_LIBC_INLINE long |
|
|
78 atol( const char *nptr ) |
|
|
79 { |
|
|
80 return strtol( nptr, (char **)NULL, 10 ); |
|
|
81 } // atol() |
|
|
82 |
|
|
83 //=========================================================================== |
|
|
84 |
|
|
85 // 7.10.6 Integer arithmetic functions |
|
|
86 |
|
|
87 |
|
|
88 CYGPRI_LIBC_INLINE int |
|
2
|
89 abs( int __j ) |
|
0
|
90 { |
|
2
|
91 return (__j<0) ? -__j : __j; |
|
0
|
92 } // abs() |
|
|
93 |
|
|
94 |
|
|
95 CYGPRI_LIBC_INLINE div_t |
|
2
|
96 div( int __numer, int __denom ) |
|
0
|
97 { |
|
2
|
98 div_t __ret; |
|
|
99 |
|
|
100 CYG_REPORT_FUNCNAMETYPE( "div", "quotient: %d"); |
|
|
101 CYG_REPORT_FUNCARG2DV( __numer, __denom ); |
|
|
102 // FIXME: what if they want it handled with SIGFPE? Should have option |
|
|
103 CYG_PRECONDITION(__denom != 0, "division by zero attempted!"); |
|
0
|
104 |
|
2
|
105 __ret.quot = __numer / __denom; |
|
|
106 __ret.rem = __numer % __denom; |
|
|
107 |
|
|
108 // But the modulo is implementation-defined for -ve numbers (ISO C 6.3.5) |
|
|
109 // and we are required to "round" to zero (ISO C 7.10.6.2) |
|
0
|
110 // |
|
2
|
111 // The cases we have to deal with are inexact division of: |
|
|
112 // a) + div + |
|
|
113 // b) + div - |
|
|
114 // c) - div + |
|
|
115 // d) - div - |
|
0
|
116 // |
|
2
|
117 // a) can never go wrong and the quotient and remainder are always positive |
|
|
118 // b) only goes wrong if the negative quotient has been "rounded" to |
|
|
119 // -infinity - if so then the remainder will be negative when it |
|
|
120 // should be positive or zero |
|
|
121 // c) only goes wrong if the negative quotient has been "rounded" to |
|
|
122 // -infinity - if so then the remainder will be positive when it |
|
|
123 // should be negative or zero |
|
|
124 // d) only goes wrong if the positive quotient has been rounded to |
|
|
125 // +infinity - if so then the remainder will be positive when it |
|
|
126 // should be negative or zero |
|
0
|
127 // |
|
2
|
128 // So the correct sign of the remainder corresponds to the sign of the |
|
|
129 // numerator. Which means we can say that the result needs adjusting |
|
|
130 // iff the sign of the numerator is different from the sign of the |
|
|
131 // remainder. |
|
|
132 // |
|
|
133 // You may be interested to know that the Berkeley version of div() |
|
|
134 // would get this wrong for e.g. (c) and (d) on some targets. |
|
|
135 // e.g. for (-5)/4 it could leave the result as -2R3 |
|
0
|
136 |
|
2
|
137 if ((__ret.rem < 0) && (__numer > 0)) { |
|
|
138 ++__ret.quot; |
|
|
139 __ret.rem -= __denom; |
|
|
140 } else if ((__ret.rem > 0) && (__numer < 0)) { |
|
|
141 --__ret.quot; |
|
|
142 __ret.rem += __denom; |
|
|
143 } // else |
|
0
|
144 |
|
2
|
145 CYG_REPORT_RETVAL( __ret.quot ); |
|
0
|
146 |
|
2
|
147 return __ret; |
|
0
|
148 } // div() |
|
|
149 |
|
|
150 |
|
|
151 CYGPRI_LIBC_INLINE long |
|
2
|
152 labs( long __j ) |
|
0
|
153 { |
|
2
|
154 return (__j<0) ? -__j : __j; |
|
0
|
155 } // labs() |
|
|
156 |
|
|
157 |
|
|
158 CYGPRI_LIBC_INLINE ldiv_t |
|
2
|
159 ldiv( long __numer, long __denom ) |
|
0
|
160 { |
|
2
|
161 ldiv_t __ret; |
|
0
|
162 |
|
2
|
163 CYG_REPORT_FUNCNAMETYPE( "ldiv", "quotient: %d"); |
|
|
164 CYG_REPORT_FUNCARG2DV( __numer, __denom ); |
|
|
165 // FIXME: what if they want it handled with SIGFPE? Should have option |
|
|
166 CYG_PRECONDITION(__denom != 0, "division by zero attempted!"); |
|
|
167 |
|
|
168 __ret.quot = __numer / __denom; |
|
|
169 __ret.rem = __numer % __denom; |
|
0
|
170 |
|
2
|
171 // But the modulo is implementation-defined for -ve numbers (ISO C 6.3.5) |
|
|
172 // and we are required to "round" to zero (ISO C 7.10.6.2) |
|
|
173 // |
|
|
174 // The cases we have to deal with are inexact division of: |
|
|
175 // a) + div + |
|
|
176 // b) + div - |
|
|
177 // c) - div + |
|
|
178 // d) - div - |
|
|
179 // |
|
|
180 // a) can never go wrong and the quotient and remainder are always positive |
|
|
181 // b) only goes wrong if the negative quotient has been "rounded" to |
|
|
182 // -infinity - if so then the remainder will be negative when it |
|
|
183 // should be positive or zero |
|
|
184 // c) only goes wrong if the negative quotient has been "rounded" to |
|
|
185 // -infinity - if so then the remainder will be positive when it |
|
|
186 // should be negative or zero |
|
|
187 // d) only goes wrong if the positive quotient has been rounded to |
|
|
188 // +infinity - if so then the remainder will be positive when it |
|
|
189 // should be negative or zero |
|
|
190 // |
|
|
191 // So the correct sign of the remainder corresponds to the sign of the |
|
|
192 // numerator. Which means we can say that the result needs adjusting |
|
|
193 // iff the sign of the numerator is different from the sign of the |
|
|
194 // remainder. |
|
|
195 // |
|
|
196 // You may be interested to know that the Berkeley version of ldiv() |
|
|
197 // would get this wrong for e.g. (c) and (d) on some targets. |
|
|
198 // e.g. for (-5)/4 it could leave the result as -2R3 |
|
0
|
199 |
|
2
|
200 if ((__ret.rem < 0) && (__numer > 0)) { |
|
|
201 ++__ret.quot; |
|
|
202 __ret.rem -= __denom; |
|
|
203 } else if ((__ret.rem > 0) && (__numer < 0)) { |
|
|
204 --__ret.quot; |
|
|
205 __ret.rem += __denom; |
|
|
206 } // else |
|
|
207 |
|
|
208 CYG_REPORT_RETVAL( __ret.quot ); |
|
|
209 |
|
|
210 return __ret; |
|
0
|
211 } // ldiv() |
|
|
212 |
|
|
213 |
|
|
214 #endif // CYGONCE_LIBC_STDLIB_INL multiple inclusion protection |
|
|
215 |
|
|
216 // EOF stdlib.inl |