Skip to content

Commit

Permalink
Fix issues in Float's mod and floordiv
Browse files Browse the repository at this point in the history
  • Loading branch information
cflee committed Apr 3, 2016
1 parent dde8c96 commit e890e6c
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions python/common/org/python/types/Float.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.python.types;

public class Float extends org.python.types.Object {
private static final long NEGATIVE_ZERO_RAW_BITS = Double.doubleToRawLongBits(-0.0);
public double value;

/**
Expand Down Expand Up @@ -208,19 +209,19 @@ public org.python.Object __truediv__(org.python.Object other) {
public org.python.Object __floordiv__(org.python.Object other) {
if (other instanceof org.python.types.Int) {
if (((org.python.types.Int) other).value == 0) {
throw new org.python.exceptions.ZeroDivisionError("integer division or modulo by zero");
throw new org.python.exceptions.ZeroDivisionError("float divmod()");
}
return new org.python.types.Float((long) Math.floor((double) this.value / ((org.python.types.Int) other).value));
return new org.python.types.Float(Math.floor((double) this.value / ((org.python.types.Int) other).value));
} else if (other instanceof org.python.types.Float) {
if (((org.python.types.Float) other).value == 0.0) {
throw new org.python.exceptions.ZeroDivisionError("float divmod()");
}
return new org.python.types.Float(Math.floor(this.value / ((org.python.types.Float) other).value));
} else if (other instanceof org.python.types.Bool) {
if (((org.python.types.Bool) other).value) {
return new org.python.types.Float((long) this.value);
return new org.python.types.Float(Math.floor(this.value));
} else {
throw new org.python.exceptions.ZeroDivisionError("integer division or modulo by zero");
throw new org.python.exceptions.ZeroDivisionError("float divmod()");
}
}
throw new org.python.exceptions.TypeError("unsupported operand type(s) for //: 'float' and '" + other.typeName() + "'");
Expand All @@ -233,7 +234,7 @@ public org.python.Object __mod__(org.python.Object other) {
try {
if (other instanceof org.python.types.Bool) {
if (((org.python.types.Bool) other).value) {
return new org.python.types.Float(this.value - (long) this.value);
return new org.python.types.Float(this.value - Math.floor(this.value));
} else {
throw new org.python.exceptions.ZeroDivisionError("integer division or modulo by zero");
}
Expand All @@ -250,6 +251,10 @@ public org.python.Object __mod__(org.python.Object other) {
// second operand is negative, ensure that result is negative
result += other_val; // subtract other_val, which is negative
}
if (other_val < 0 && result >= 0
&& Double.doubleToRawLongBits(result) != NEGATIVE_ZERO_RAW_BITS) {
result *= -1;
}
return new org.python.types.Float(result);
}
} else if (other instanceof org.python.types.Float) {
Expand All @@ -265,9 +270,10 @@ public org.python.Object __mod__(org.python.Object other) {
// second operand is negative, ensure that result is negative
result += other_val; // subtract other_val, which is negative
}
// edge case where operands are 0 and -0.0:
// need to force sign to negative as adding -0.0 to 0.0 doesn't yield the expected -0.0
if (other_val < 0.0 && result >= 0.0) {
// edge case where adding -0.0 to 0.0 doesn't yield the expected -0.0
// do this only if it is definitely not -0.0 already
if (other_val < 0.0 && result >= 0.0
&& Double.doubleToRawLongBits(result) != NEGATIVE_ZERO_RAW_BITS) {
result *= -1;
}
return new org.python.types.Float(result);
Expand Down

0 comments on commit e890e6c

Please sign in to comment.