@@ -230,31 +230,71 @@ int_rem(v, w)
230230 return newintobject (v -> ob_ival % ((intobject * )w ) -> ob_ival );
231231}
232232
233+ static object *
234+ int_divmod (x , y )
235+ intobject * x ;
236+ register object * y ;
237+ {
238+ object * v , * v0 , * v1 ;
239+ long xi , yi , xdivy , xmody ;
240+ if (!is_intobject (y )) {
241+ err_badarg ();
242+ return NULL ;
243+ }
244+ xi = x -> ob_ival ;
245+ yi = getintvalue (y );
246+ if (yi == 0 )
247+ return err_zdiv ();
248+ if (yi < 0 ) {
249+ xdivy = - xi / - yi ;
250+ }
251+ else {
252+ xdivy = xi / yi ;
253+ }
254+ xmody = xi - xdivy * yi ;
255+ if (xmody < 0 && yi > 0 || xmody > 0 && yi < 0 ) {
256+ xmody += yi ;
257+ xdivy -= 1 ;
258+ }
259+ v = newtupleobject (2 );
260+ v0 = newintobject (xdivy );
261+ v1 = newintobject (xmody );
262+ if (v == NULL || v0 == NULL || v1 == NULL ||
263+ settupleitem (v , 0 , v0 ) != 0 ||
264+ settupleitem (v , 1 , v1 ) != 0 ) {
265+ XDECREF (v );
266+ XDECREF (v0 );
267+ XDECREF (v1 );
268+ v = NULL ;
269+ }
270+ return v ;
271+ }
272+
233273static object *
234274int_pow (v , w )
235275 intobject * v ;
236276 register object * w ;
237277{
238278 register long iv , iw , ix ;
239- register int neg ;
240279 if (!is_intobject (w )) {
241280 err_badarg ();
242281 return NULL ;
243282 }
244283 iv = v -> ob_ival ;
245284 iw = ((intobject * )w )-> ob_ival ;
246- neg = 0 ;
247- if (iw < 0 )
248- neg = 1 , iw = - iw ;
285+ if (iw < 0 ) {
286+ err_setstr (RuntimeError , "integer to the negative power" );
287+ return NULL ;
288+ }
249289 ix = 1 ;
250- for (; iw > 0 ; iw -- )
290+ while (-- iw >= 0 ) {
291+ long prev = ix ;
251292 ix = ix * iv ;
252- if (neg ) {
253- if ( ix == 0 )
254- return err_zdiv ();
255- ix = 1 / ix ;
293+ if (iv == 0 )
294+ break ; /* 0 to some power -- avoid ix / 0 */
295+ if ( ix / iv != prev )
296+ return err_ovf () ;
256297 }
257- /* XXX How to check for overflow? */
258298 return newintobject (ix );
259299}
260300
@@ -278,15 +318,27 @@ int_pos(v)
278318 return (object * )v ;
279319}
280320
321+ static object *
322+ int_abs (v )
323+ intobject * v ;
324+ {
325+ if (v -> ob_ival >= 0 )
326+ return int_pos (v );
327+ else
328+ return int_neg (v );
329+ }
330+
281331static number_methods int_as_number = {
282- int_add , /*tp_add*/
283- int_sub , /*tp_subtract*/
284- int_mul , /*tp_multiply*/
285- int_div , /*tp_divide*/
286- int_rem , /*tp_remainder*/
287- int_pow , /*tp_power*/
288- int_neg , /*tp_negate*/
289- int_pos , /*tp_plus*/
332+ int_add , /*nb_add*/
333+ int_sub , /*nb_subtract*/
334+ int_mul , /*nb_multiply*/
335+ int_div , /*nb_divide*/
336+ int_rem , /*nb_remainder*/
337+ int_divmod , /*nb_divmod*/
338+ int_pow , /*nb_power*/
339+ int_neg , /*nb_negative*/
340+ int_pos , /*nb_positive*/
341+ int_abs , /*nb_absolute*/
290342};
291343
292344typeobject Inttype = {
0 commit comments