Skip to content

Commit e6966ff

Browse files
committed
Fixed handling of signs in float mod and divmod
1 parent a28b6bc commit e6966ff

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
9696
import com.oracle.graal.python.builtins.objects.complex.PComplex;
9797
import com.oracle.graal.python.builtins.objects.dict.PDict;
98+
import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins;
9899
import com.oracle.graal.python.builtins.objects.floats.PFloat;
99100
import com.oracle.graal.python.builtins.objects.frame.PFrame;
100101
import com.oracle.graal.python.builtins.objects.function.PArguments;
@@ -519,8 +520,11 @@ public PTuple doLongZero(long a, long b) {
519520

520521
@Specialization
521522
public PTuple doDouble(double a, double b) {
523+
if (b == 0) {
524+
throw raise(PythonErrorType.ZeroDivisionError, ErrorMessages.DIVISION_BY_ZERO);
525+
}
522526
double q = Math.floor(a / b);
523-
return factory().createTuple(new Object[]{q, a % b});
527+
return factory().createTuple(new Object[]{q, FloatBuiltins.ModNode.op(a, b)});
524528
}
525529

526530
@Specialization

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/floats/FloatBuiltins.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -608,19 +608,19 @@ abstract static class DivModNode extends FloatBinaryBuiltinNode {
608608
@Specialization
609609
PTuple doDL(double left, long right) {
610610
raiseDivisionByZero(right == 0);
611-
return factory().createTuple(new Object[]{Math.floor(left / right), left % right});
611+
return factory().createTuple(new Object[]{Math.floor(left / right), ModNode.op(left, right)});
612612
}
613613

614614
@Specialization
615615
PTuple doDD(double left, double right) {
616616
raiseDivisionByZero(right == 0.0);
617-
return factory().createTuple(new Object[]{Math.floor(left / right), left % right});
617+
return factory().createTuple(new Object[]{Math.floor(left / right), ModNode.op(left, right)});
618618
}
619619

620620
@Specialization
621621
PTuple doLD(long left, double right) {
622622
raiseDivisionByZero(right == 0.0);
623-
return factory().createTuple(new Object[]{Math.floor(left / right), left % right});
623+
return factory().createTuple(new Object[]{Math.floor(left / right), ModNode.op(left, right)});
624624
}
625625

626626
@Specialization(guards = {"accepts(left)", "accepts(right)"})
@@ -820,42 +820,54 @@ public String hexD(double value) {
820820
@Builtin(name = __MOD__, minNumOfPositionalArgs = 2)
821821
@TypeSystemReference(PythonArithmeticTypes.class)
822822
@GenerateNodeFactory
823-
abstract static class ModNode extends FloatBinaryBuiltinNode {
823+
public abstract static class ModNode extends FloatBinaryBuiltinNode {
824824
@Specialization
825825
double doDL(double left, long right) {
826826
raiseDivisionByZero(right == 0);
827-
return left % right;
827+
return op(left, right);
828828
}
829829

830830
@Specialization
831831
double doDL(double left, PInt right) {
832832
raiseDivisionByZero(right.isZero());
833-
return left % right.doubleValue();
833+
return op(left, right.doubleValue());
834834
}
835835

836836
@Specialization
837837
double doDD(double left, double right) {
838838
raiseDivisionByZero(right == 0.0);
839-
return left % right;
839+
return op(left, right);
840840
}
841841

842842
@Specialization
843843
double doLD(long left, double right) {
844844
raiseDivisionByZero(right == 0.0);
845-
return left % right;
845+
return op(left, right);
846846
}
847847

848848
@Specialization
849849
double doPiD(PInt left, double right) {
850850
raiseDivisionByZero(right == 0.0);
851-
return left.doubleValue() % right;
851+
return op(left.doubleValue(), right);
852852
}
853853

854854
@SuppressWarnings("unused")
855855
@Fallback
856856
PNotImplemented doGeneric(Object right, Object left) {
857857
return PNotImplemented.NOT_IMPLEMENTED;
858858
}
859+
860+
public static double op(double left, double right) {
861+
double mod = left % right;
862+
if (mod != 0.0) {
863+
if ((right < 0) != (mod < 0)) {
864+
mod += right;
865+
}
866+
} else {
867+
mod = right < 0 ? -0.0 : 0.0;
868+
}
869+
return mod;
870+
}
859871
}
860872

861873
@Builtin(name = __RTRUEDIV__, minNumOfPositionalArgs = 2, reverseOperation = true)

0 commit comments

Comments
 (0)