@@ -398,8 +398,8 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
398398/**end repeat1**/
399399
400400/**begin repeat1
401- * #kind = atan2,hypot,pow,copysign#
402- * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
401+ * #kind = atan2,hypot,pow,fmod, copysign#
402+ * #KIND = ATAN2,HYPOT,POW,FMOD, COPYSIGN#
403403 */
404404#ifdef @kind @@c @
405405#undef @kind@@c@
@@ -412,32 +412,6 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
412412#endif
413413/**end repeat1**/
414414
415- /**begin repeat1
416- * #kind = fmod#
417- * #KIND = FMOD#
418- */
419- #ifdef @kind @@c @
420- #undef @kind@@c@
421- #endif
422- #ifndef HAVE_MODF @C @
423- NPY_INPLACE @type @
424- npy_ @kind @@c @(@type @ x , @type @ y )
425- {
426- int are_inputs_inf = (npy_isinf (x ) && npy_isinf (y ));
427- /* force set invalid flag, doesnt raise by default on gcc < 8 */
428- if (npy_isnan (x ) || npy_isnan (y )) {
429- npy_set_floatstatus_invalid ();
430- }
431- if (are_inputs_inf || !y ) {
432- if (!npy_isnan (x )) {
433- npy_set_floatstatus_invalid ();
434- }
435- }
436- return (@type @) npy_ @kind @((double )x , (double ) y );
437- }
438- #endif
439- /**end repeat1**/
440-
441415#ifdef modf @c @
442416#undef modf@c@
443417#endif
@@ -499,8 +473,8 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
499473/**end repeat1**/
500474
501475/**begin repeat1
502- * #kind = atan2,hypot,pow,copysign#
503- * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
476+ * #kind = atan2,hypot,pow,fmod, copysign#
477+ * #KIND = ATAN2,HYPOT,POW,FMOD, COPYSIGN#
504478 */
505479#ifdef HAVE_ @KIND @@C @
506480NPY_INPLACE @type @ npy_ @kind @@c @(@type @ x , @type @ y )
@@ -510,29 +484,6 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
510484#endif
511485/**end repeat1**/
512486
513- /**begin repeat1
514- * #kind = fmod#
515- * #KIND = FMOD#
516- */
517- #ifdef HAVE_FMOD @C @
518- NPY_INPLACE @type @
519- npy_ @kind @@c @(@type @ x , @type @ y )
520- {
521- int are_inputs_inf = (npy_isinf (x ) && npy_isinf (y ));
522- /* force set invalid flag, doesnt raise by default on gcc < 8 */
523- if (npy_isnan (x ) || npy_isnan (y )) {
524- npy_set_floatstatus_invalid ();
525- }
526- if (are_inputs_inf || !y ) {
527- if (!npy_isnan (x )) {
528- npy_set_floatstatus_invalid ();
529- }
530- }
531- return @kind @@c @(x , y );
532- }
533- #endif
534- /**end repeat1**/
535-
536487#ifdef HAVE_MODF @C @
537488NPY_INPLACE @type @ npy_modf @c @(@type @ x , @type @ * iptr )
538489{
@@ -682,8 +633,14 @@ npy_remainder@c@(@type@ a, @type@ b)
682633{
683634 @type @ mod ;
684635 if (NPY_UNLIKELY (!b )) {
636+ /*
637+ * in2 == 0 (and not NaN): normal fmod will give the correct
638+ * result (always NaN). `divmod` may set additional FPE for the
639+ * division by zero creating an inf.
640+ */
685641 mod = npy_fmod @c @(a , b );
686- } else {
642+ }
643+ else {
687644 npy_divmod @c @(a , b , & mod );
688645 }
689646 return mod ;
@@ -693,13 +650,14 @@ NPY_INPLACE @type@
693650npy_floor_divide @c @(@type @ a , @type @ b ) {
694651 @type @ div , mod ;
695652 if (NPY_UNLIKELY (!b )) {
653+ /*
654+ * in2 == 0 (and not NaN): normal division will give the correct
655+ * result (Inf or NaN). `divmod` may set additional FPE for the modulo
656+ * evaluating to NaN.
657+ */
696658 div = a / b ;
697- if (!a || npy_isnan (a )) {
698- npy_set_floatstatus_invalid ();
699- } else {
700- npy_set_floatstatus_divbyzero ();
701- }
702- } else {
659+ }
660+ else {
703661 div = npy_divmod @c @(a , b , & mod );
704662 }
705663 return div ;
@@ -715,27 +673,19 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
715673{
716674 @type @ div , mod , floordiv ;
717675
718- /* force set invalid flag, doesnt raise by default on gcc < 8 */
719- if (npy_isnan (a ) || npy_isnan (b )) {
720- npy_set_floatstatus_invalid ();
721- }
722676 mod = npy_fmod @c @(a , b );
723677 if (NPY_UNLIKELY (!b )) {
724- div = a / b ;
725- if (a && !npy_isnan (a )) {
726- npy_set_floatstatus_divbyzero ();
727- }
728- /* If b == 0, return result of fmod. For IEEE is nan */
678+ /* b == 0 (not NaN): return result of fmod. For IEEE is nan */
729679 * modulus = mod ;
730- return div ;
680+ return a / b ;
731681 }
732682
733683 /* a - mod should be very nearly an integer multiple of b */
734684 div = (a - mod ) / b ;
735685
736686 /* adjust fmod result to conform to Python convention of remainder */
737687 if (mod ) {
738- if (( b < 0 ) != (mod < 0 )) {
688+ if (isless ( b , 0 ) != isless (mod , 0 )) {
739689 mod += b ;
740690 div -= 1.0 @c @;
741691 }
@@ -748,7 +698,7 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
748698 /* snap quotient to nearest integral value */
749699 if (div ) {
750700 floordiv = npy_floor @c @(div );
751- if (div - floordiv > 0.5 @c @)
701+ if (isgreater ( div - floordiv , 0.5 @c @) )
752702 floordiv += 1.0 @c @;
753703 }
754704 else {
0 commit comments