@@ -611,64 +611,72 @@ float_rem(PyObject *v, PyObject *w)
611611 return PyFloat_FromDouble (mod );
612612}
613613
614- static PyObject *
615- float_divmod ( PyObject * v , PyObject * w )
614+ static void
615+ _float_div_mod ( double vx , double wx , double * floordiv , double * mod )
616616{
617- double vx , wx ;
618- double div , mod , floordiv ;
619- CONVERT_TO_DOUBLE (v , vx );
620- CONVERT_TO_DOUBLE (w , wx );
621- if (wx == 0.0 ) {
622- PyErr_SetString (PyExc_ZeroDivisionError , "float divmod()" );
623- return NULL ;
624- }
625- mod = fmod (vx , wx );
617+ double div ;
618+ * mod = fmod (vx , wx );
626619 /* fmod is typically exact, so vx-mod is *mathematically* an
627620 exact multiple of wx. But this is fp arithmetic, and fp
628621 vx - mod is an approximation; the result is that div may
629622 not be an exact integral value after the division, although
630623 it will always be very close to one.
631624 */
632- div = (vx - mod ) / wx ;
633- if (mod ) {
625+ div = (vx - * mod ) / wx ;
626+ if (* mod ) {
634627 /* ensure the remainder has the same sign as the denominator */
635- if ((wx < 0 ) != (mod < 0 )) {
636- mod += wx ;
628+ if ((wx < 0 ) != (* mod < 0 )) {
629+ * mod += wx ;
637630 div -= 1.0 ;
638631 }
639632 }
640633 else {
641634 /* the remainder is zero, and in the presence of signed zeroes
642635 fmod returns different results across platforms; ensure
643636 it has the same sign as the denominator. */
644- mod = copysign (0.0 , wx );
637+ * mod = copysign (0.0 , wx );
645638 }
646639 /* snap quotient to nearest integral value */
647640 if (div ) {
648- floordiv = floor (div );
649- if (div - floordiv > 0.5 )
650- floordiv += 1.0 ;
641+ * floordiv = floor (div );
642+ if (div - * floordiv > 0.5 ) {
643+ * floordiv += 1.0 ;
644+ }
651645 }
652646 else {
653647 /* div is zero - get the same sign as the true quotient */
654- floordiv = copysign (0.0 , vx / wx ); /* zero w/ sign of vx/wx */
648+ * floordiv = copysign (0.0 , vx / wx ); /* zero w/ sign of vx/wx */
655649 }
656- return Py_BuildValue ("(dd)" , floordiv , mod );
650+ }
651+
652+ static PyObject *
653+ float_divmod (PyObject * v , PyObject * w )
654+ {
655+ double vx , wx ;
656+ double mod , floordiv ;
657+ CONVERT_TO_DOUBLE (v , vx );
658+ CONVERT_TO_DOUBLE (w , wx );
659+ if (wx == 0.0 ) {
660+ PyErr_SetString (PyExc_ZeroDivisionError , "float divmod()" );
661+ return NULL ;
662+ }
663+ _float_div_mod (vx , wx , & floordiv , & mod );
664+ return Py_BuildValue ("(dd)" , floordiv , mod );
657665}
658666
659667static PyObject *
660668float_floor_div (PyObject * v , PyObject * w )
661669{
662- PyObject * t , * r ;
663-
664- t = float_divmod (v , w );
665- if ( t == NULL || t == Py_NotImplemented )
666- return t ;
667- assert ( PyTuple_CheckExact ( t ) );
668- r = PyTuple_GET_ITEM ( t , 0 ) ;
669- Py_INCREF ( r );
670- Py_DECREF ( t );
671- return r ;
670+ double vx , wx ;
671+ double mod , floordiv ;
672+ CONVERT_TO_DOUBLE (v , vx );
673+ CONVERT_TO_DOUBLE ( w , wx );
674+ if ( wx == 0.0 ) {
675+ PyErr_SetString ( PyExc_ZeroDivisionError , "float floor division by zero" );
676+ return NULL ;
677+ }
678+ _float_div_mod ( vx , wx , & floordiv , & mod );
679+ return PyFloat_FromDouble ( floordiv ) ;
672680}
673681
674682/* determine whether x is an odd integer or not; assumes that
0 commit comments