comparison packages/language/c/libc/stdlib/current/include/div.inl @ 115:6ed91473a1cd ecos-sw-2000-08-21

Merge from eCos master repository on 2000-08-21-22:40:54-BST
author jlarmour
date Fri, 25 Aug 2000 17:32:38 +0000
parents
children e0c0827131d1
comparison
equal deleted inserted replaced
114:5ad2b71d525e 115:6ed91473a1cd
1 #ifndef CYGONCE_LIBC_STDLIB_DIV_INL
2 #define CYGONCE_LIBC_STDLIB_DIV_INL
3 /*===========================================================================
4 //
5 // div.inl
6 //
7 // Inline implementations for the ISO standard utility functions
8 // div() and ldiv()
9 //
10 //===========================================================================
11 //####COPYRIGHTBEGIN####
12 //
13 // -------------------------------------------
14 // The contents of this file are subject to the Red Hat eCos Public License
15 // Version 1.1 (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://www.redhat.com/
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 Configurable Operating System,
25 // released September 30, 1998.
26 //
27 // The Initial Developer of the Original Code is Red Hat.
28 // Portions created by Red Hat are
29 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
30 // All Rights Reserved.
31 // -------------------------------------------
32 //
33 //####COPYRIGHTEND####
34 //===========================================================================
35 //#####DESCRIPTIONBEGIN####
36 //
37 // Author(s): jlarmour
38 // Contributors:
39 // Date: 2000-04-28
40 // Purpose:
41 // Description:
42 // Usage: Do not include this file directly - include <stdlib.h> instead
43 //
44 //####DESCRIPTIONEND####
45 //
46 //=========================================================================*/
47
48 // CONFIGURATION
49
50 #include <pkgconf/libc_stdlib.h> // Configuration header
51
52 // INCLUDES
53
54 #include <cyg/infra/cyg_ass.h> // Assertion support
55 #include <cyg/infra/cyg_trac.h> // Tracing support
56
57 /* TYPE DEFINITIONS */
58
59 /* return type of the div() function */
60
61 typedef struct {
62 int quot; /* quotient */
63 int rem; /* remainder */
64 } div_t;
65
66
67 /* return type of the ldiv() function */
68
69 typedef struct {
70 long quot; /* quotient */
71 long rem; /* remainder */
72 } ldiv_t;
73
74 /* FUNCTION PROTOTYPES */
75
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79
80 extern div_t
81 div( int /* numerator */, int /* denominator */ ) __attribute__((__const__));
82
83 extern ldiv_t
84 ldiv( long /* numerator */, long /* denominator */ ) __attribute__((__const__));
85
86 #ifdef __cplusplus
87 } /* extern "C" */
88 #endif
89
90 /* FUNCTIONS */
91
92 #ifndef CYGPRI_LIBC_STDLIB_DIV_INLINE
93 # define CYGPRI_LIBC_STDLIB_DIV_INLINE extern __inline__
94 #endif
95
96 CYGPRI_LIBC_STDLIB_DIV_INLINE div_t
97 div( int __numer, int __denom )
98 {
99 div_t __ret;
100
101 CYG_REPORT_FUNCNAMETYPE( "div", "quotient: %d");
102 CYG_REPORT_FUNCARG2DV( __numer, __denom );
103 // FIXME: what if they want it handled with SIGFPE? Should have option
104 CYG_PRECONDITION(__denom != 0, "division by zero attempted!");
105
106 __ret.quot = __numer / __denom;
107 __ret.rem = __numer % __denom;
108
109 // But the modulo is implementation-defined for -ve numbers (ISO C 6.3.5)
110 // and we are required to "round" to zero (ISO C 7.10.6.2)
111 //
112 // The cases we have to deal with are inexact division of:
113 // a) + div +
114 // b) + div -
115 // c) - div +
116 // d) - div -
117 //
118 // a) can never go wrong and the quotient and remainder are always positive
119 // b) only goes wrong if the negative quotient has been "rounded" to
120 // -infinity - if so then the remainder will be negative when it
121 // should be positive or zero
122 // c) only goes wrong if the negative quotient has been "rounded" to
123 // -infinity - if so then the remainder will be positive when it
124 // should be negative or zero
125 // d) only goes wrong if the positive quotient has been rounded to
126 // +infinity - if so then the remainder will be positive when it
127 // should be negative or zero
128 //
129 // So the correct sign of the remainder corresponds to the sign of the
130 // numerator. Which means we can say that the result needs adjusting
131 // iff the sign of the numerator is different from the sign of the
132 // remainder.
133 //
134 // You may be interested to know that the Berkeley version of div()
135 // would get this wrong for e.g. (c) and (d) on some targets.
136 // e.g. for (-5)/4 it could leave the result as -2R3
137
138 if ((__ret.rem < 0) && (__numer > 0)) {
139 ++__ret.quot;
140 __ret.rem -= __denom;
141 } else if ((__ret.rem > 0) && (__numer < 0)) {
142 --__ret.quot;
143 __ret.rem += __denom;
144 } // else
145
146 CYG_REPORT_RETVAL( __ret.quot );
147
148 return __ret;
149 } // div()
150
151 CYGPRI_LIBC_STDLIB_DIV_INLINE ldiv_t
152 ldiv( long __numer, long __denom )
153 {
154 ldiv_t __ret;
155
156 CYG_REPORT_FUNCNAMETYPE( "ldiv", "quotient: %d");
157 CYG_REPORT_FUNCARG2DV( __numer, __denom );
158 // FIXME: what if they want it handled with SIGFPE? Should have option
159 CYG_PRECONDITION(__denom != 0, "division by zero attempted!");
160
161 __ret.quot = __numer / __denom;
162 __ret.rem = __numer % __denom;
163
164 // But the modulo is implementation-defined for -ve numbers (ISO C 6.3.5)
165 // and we are required to "round" to zero (ISO C 7.10.6.2)
166 //
167 // The cases we have to deal with are inexact division of:
168 // a) + div +
169 // b) + div -
170 // c) - div +
171 // d) - div -
172 //
173 // a) can never go wrong and the quotient and remainder are always positive
174 // b) only goes wrong if the negative quotient has been "rounded" to
175 // -infinity - if so then the remainder will be negative when it
176 // should be positive or zero
177 // c) only goes wrong if the negative quotient has been "rounded" to
178 // -infinity - if so then the remainder will be positive when it
179 // should be negative or zero
180 // d) only goes wrong if the positive quotient has been rounded to
181 // +infinity - if so then the remainder will be positive when it
182 // should be negative or zero
183 //
184 // So the correct sign of the remainder corresponds to the sign of the
185 // numerator. Which means we can say that the result needs adjusting
186 // iff the sign of the numerator is different from the sign of the
187 // remainder.
188 //
189 // You may be interested to know that the Berkeley version of ldiv()
190 // would get this wrong for e.g. (c) and (d) on some targets.
191 // e.g. for (-5)/4 it could leave the result as -2R3
192
193 if ((__ret.rem < 0) && (__numer > 0)) {
194 ++__ret.quot;
195 __ret.rem -= __denom;
196 } else if ((__ret.rem > 0) && (__numer < 0)) {
197 --__ret.quot;
198 __ret.rem += __denom;
199 } // else
200
201 CYG_REPORT_RETVAL( __ret.quot );
202
203 return __ret;
204 } // ldiv()
205
206
207 #endif // CYGONCE_LIBC_STDLIB_DIV_INL multiple inclusion protection
208
209 // EOF div.inl