@@ -611,64 +611,72 @@ float_rem(PyObject *v, PyObject *w)
611
611
return PyFloat_FromDouble (mod );
612
612
}
613
613
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 )
616
616
{
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 );
626
619
/* fmod is typically exact, so vx-mod is *mathematically* an
627
620
exact multiple of wx. But this is fp arithmetic, and fp
628
621
vx - mod is an approximation; the result is that div may
629
622
not be an exact integral value after the division, although
630
623
it will always be very close to one.
631
624
*/
632
- div = (vx - mod ) / wx ;
633
- if (mod ) {
625
+ div = (vx - * mod ) / wx ;
626
+ if (* mod ) {
634
627
/* 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 ;
637
630
div -= 1.0 ;
638
631
}
639
632
}
640
633
else {
641
634
/* the remainder is zero, and in the presence of signed zeroes
642
635
fmod returns different results across platforms; ensure
643
636
it has the same sign as the denominator. */
644
- mod = copysign (0.0 , wx );
637
+ * mod = copysign (0.0 , wx );
645
638
}
646
639
/* snap quotient to nearest integral value */
647
640
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
+ }
651
645
}
652
646
else {
653
647
/* 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 */
655
649
}
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 );
657
665
}
658
666
659
667
static PyObject *
660
668
float_floor_div (PyObject * v , PyObject * w )
661
669
{
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 ) ;
672
680
}
673
681
674
682
/* determine whether x is an odd integer or not; assumes that
0 commit comments