You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2020/04/16 12:18:15 UTC
[commons-numbers] branch master updated (c876c0c -> 69f7ddc)
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git.
from c876c0c FractionTest: zero divide should be equal to Fraction.ZERO
new 828f6a7 Fraction: Add tests for two representations of zero.
new 7ad0f91 Use consistent order and tests in FractionTest and BigFractionTest.
new 36154bb Fixed Fraction.compareTo
new 7fa4f4b Rename powFractionTestCases to powTestCases
new bb645f6 Fraction: Increase similarity between BigFraction tests
new 51419db BigFraction: Remove pow(long/BigInteger)
new bcdbb3f Fraction: common test cases for arithmetic with an integer
new 854d141 Fraction: fix compareTo for positive numbers with two negative parts
new fa5b3ee Fraction: Use canonical zero as 0 / 1
new 4356bd9 Fraction: update toString()
new 4002f40 Fraction: efficient multiply by integer
new 368187d Fraction: efficient divide by integer
new 6794743 Fraction: Optimise divide by fraction
new e55c35b FractionTest: use assertFraction in testMath1261
new b47f05e Clean-up numbers core TestUtilities.
new 7d64af5 Remove unused import
new 5192e10 Fraction: use factory constructor in add/subtract
new e3f69b7 Fraction: fix overflow detection in add/subtract int
new 83098b7 FractionTest: overflow check in multiply/divide by int
new b0164fb Fraction: rename f to num (for numerator) in add/subtract int
new 1e789e0 FractionTest: Create test cases for arithmetic overflow
new 86e3b5f Fraction: test for zero in add/subtract int
new c8d9fb7 Use final
new ccd5e31 Fraction: Add tests for Integer.MIN_VALUE in intValue()
new 466d33e Add integer case to double constructor test cases.
new 69f7ddc Fraction: double constructor to avoid iterations <= epsilon.
The 26 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../org/apache/commons/numbers/core/TestUtils.java | 143 +----
.../commons/numbers/fraction/BigFraction.java | 121 ++--
.../apache/commons/numbers/fraction/Fraction.java | 155 +++--
.../commons/numbers/fraction/BigFractionTest.java | 497 ++++++++--------
.../commons/numbers/fraction/CommonTestCases.java | 206 ++++++-
.../commons/numbers/fraction/FractionTest.java | 635 +++++++++++++--------
6 files changed, 1008 insertions(+), 749 deletions(-)
[commons-numbers] 23/26: Use final
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit c8d9fb72b27ffe35134559915913db859ba59c3f
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 21:43:23 2020 +0100
Use final
---
.../commons/numbers/fraction/BigFractionTest.java | 110 ++++++-------
.../commons/numbers/fraction/CommonTestCases.java | 28 ++--
.../commons/numbers/fraction/FractionTest.java | 170 ++++++++++-----------
3 files changed, 154 insertions(+), 154 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 8e4d90b..add8efd 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -60,7 +60,7 @@ public class BigFractionTest {
}
private static void assertDoubleValue(double expected, BigInteger numerator, BigInteger denominator) {
- BigFraction f = BigFraction.of(numerator, denominator);
+ final BigFraction f = BigFraction.of(numerator, denominator);
Assertions.assertEquals(expected, f.doubleValue());
}
@@ -70,7 +70,7 @@ public class BigFractionTest {
@Test
public void testConstructor() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
assertFraction(
testCase.expectedNumerator,
testCase.expectedDenominator,
@@ -115,7 +115,7 @@ public class BigFractionTest {
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
- for (CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleConstructorTestCases()) {
+ for (final CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleConstructorTestCases()) {
assertFraction(
testCase.expectedNumerator,
testCase.expectedDenominator,
@@ -324,7 +324,7 @@ public class BigFractionTest {
@Test
public void testDoubleValueForInfinities() {
//the smallest integer that rounds up to Double.POSITIVE_INFINITY
- BigInteger minInf = BigInteger.ONE
+ final BigInteger minInf = BigInteger.ONE
.shiftLeft(1024)
.subtract(BigInteger.ONE.shiftLeft(970));
@@ -464,41 +464,41 @@ public class BigFractionTest {
@Test
public void testAbs() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
- BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
+ final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.abs());
}
}
@Test
public void testReciprocal() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
- BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
+ final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.reciprocal());
}
- BigFraction f = BigFraction.of(0, 3);
+ final BigFraction f = BigFraction.of(0, 3);
Assertions.assertThrows(ArithmeticException.class, f::reciprocal);
}
@Test
public void testNegate() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.negateTestCases()) {
- BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.negateTestCases()) {
+ final BigFraction f = BigFraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.negate());
}
}
@Test
public void testAdd() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.addFractionTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.addFractionTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add((long) i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(BigInteger.valueOf(i2)));
@@ -508,21 +508,21 @@ public class BigFractionTest {
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigInteger) null));
// Special cases
- BigFraction f2 = BigFraction.of(1, 2);
+ final BigFraction f2 = BigFraction.of(1, 2);
assertFraction(1, 2, f2.add(BigInteger.ZERO));
assertFraction(12, 1, BigFraction.ZERO.add(BigInteger.valueOf(12)));
}
@Test
public void testDivide() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.divideByFractionTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.divideByFractionTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide((long) i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(BigInteger.valueOf(i2)));
@@ -537,7 +537,7 @@ public class BigFractionTest {
Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigInteger.ZERO));
// Special cases
- BigFraction f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ final BigFraction f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
assertFraction(-1, -Integer.MAX_VALUE, f1.divide(Integer.MIN_VALUE));
assertFraction(-1, -Integer.MAX_VALUE, f1.divide((long) Integer.MIN_VALUE));
assertFraction(-1, -Integer.MAX_VALUE, f1.divide(BigInteger.valueOf(Integer.MIN_VALUE)));
@@ -545,14 +545,14 @@ public class BigFractionTest {
@Test
public void testMultiply() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.multiplyByFractionTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.multiplyByFractionTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply((long) i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(BigInteger.valueOf(i2)));
@@ -564,9 +564,9 @@ public class BigFractionTest {
@Test
public void testPow() {
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int exponent = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int exponent = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
}
@@ -580,14 +580,14 @@ public class BigFractionTest {
@Test
public void testSubtract() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.subtractFractionTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.subtractFractionTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
+ final BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract((long) i2));
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(BigInteger.valueOf(i2)));
@@ -599,24 +599,24 @@ public class BigFractionTest {
@Test
public void testEqualsAndHashCode() {
- BigFraction zero = BigFraction.of(0, 1);
+ final BigFraction zero = BigFraction.of(0, 1);
Assertions.assertEquals(zero, zero);
Assertions.assertFalse(zero.equals(null));
Assertions.assertFalse(zero.equals(new Object()));
Assertions.assertFalse(zero.equals(Double.valueOf(0)));
// Equal to same rational number
- BigFraction zero2 = BigFraction.of(0, 2);
+ final BigFraction zero2 = BigFraction.of(0, 2);
assertEqualAndHashCodeEqual(zero, zero2);
// Not equal to different rational number
- BigFraction one = BigFraction.of(1, 1);
+ final BigFraction one = BigFraction.of(1, 1);
Assertions.assertNotEquals(zero, one);
Assertions.assertNotEquals(one, zero);
// Test using different representations of the same fraction
// (Denominators are primes)
- for (int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}, {0, 3}}) {
+ for (final int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}, {0, 3}}) {
final int num = f[0];
final int den = f[1];
BigFraction f1 = BigFraction.of(-num, den);
@@ -630,8 +630,8 @@ public class BigFractionTest {
}
// Same numerator or denominator as 1/1
- BigFraction half = BigFraction.of(1, 2);
- BigFraction two = BigFraction.of(2, 1);
+ final BigFraction half = BigFraction.of(1, 2);
+ final BigFraction two = BigFraction.of(2, 1);
Assertions.assertNotEquals(one, half);
Assertions.assertNotEquals(one, two);
}
@@ -671,12 +671,12 @@ public class BigFractionTest {
@Test
public void testSerial() {
- BigFraction[] fractions = {
+ final BigFraction[] fractions = {
BigFraction.of(3, 4), BigFraction.ONE, BigFraction.ZERO,
BigFraction.of(17), BigFraction.from(Math.PI, 1000),
BigFraction.of(-5, 2)
};
- for (BigFraction fraction : fractions) {
+ for (final BigFraction fraction : fractions) {
Assertions.assertEquals(fraction,
TestUtils.serializeAndRecover(fraction));
}
@@ -694,7 +694,7 @@ public class BigFractionTest {
@Test
public void testParse() {
- String[] validExpressions = new String[] {
+ final String[] validExpressions = new String[] {
"1 / 2",
"-1 / 2",
"1 / -2",
@@ -712,7 +712,7 @@ public class BigFractionTest {
"2147,483,647 / 2,147,483,648", //over largest int value
"9,223,372,036,854,775,807 / 9,223,372,036,854,775,808" //over largest long value
};
- BigFraction[] fractions = {
+ final BigFraction[] fractions = {
BigFraction.of(1, 2),
BigFraction.of(-1, 2),
BigFraction.of(1, -2),
@@ -732,7 +732,7 @@ public class BigFractionTest {
new BigInteger("9223372036854775808"))
};
int inc = 0;
- for (BigFraction fraction: fractions) {
+ for (final BigFraction fraction: fractions) {
Assertions.assertEquals(fraction,
BigFraction.parse(validExpressions[inc]));
inc++;
@@ -746,10 +746,10 @@ public class BigFractionTest {
@Test
public void testMath340() {
- BigFraction fractionA = BigFraction.from(0.00131);
- BigFraction fractionB = BigFraction.from(.37).reciprocal();
- BigFraction errorResult = fractionA.multiply(fractionB);
- BigFraction correctResult = BigFraction.of(fractionA.getNumerator().multiply(fractionB.getNumerator()),
+ final BigFraction fractionA = BigFraction.from(0.00131);
+ final BigFraction fractionB = BigFraction.from(.37).reciprocal();
+ final BigFraction errorResult = fractionA.multiply(fractionB);
+ final BigFraction correctResult = BigFraction.of(fractionA.getNumerator().multiply(fractionB.getNumerator()),
fractionA.getDenominator().multiply(fractionB.getDenominator()));
Assertions.assertEquals(correctResult, errorResult);
}
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index c582de5..b0f703f 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -123,7 +123,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<UnaryOperatorTestCase> collectNumDenConstructorTestCases() {
- List<UnaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
testCases.add(new UnaryOperatorTestCase(0, 2, 0, 1));
@@ -148,7 +148,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<DoubleToFractionTestCase> collectDoubleConstructorTestCases() {
- List<DoubleToFractionTestCase> testCases = new ArrayList<>();
+ final List<DoubleToFractionTestCase> testCases = new ArrayList<>();
testCases.add(new DoubleToFractionTestCase(1d / 2d, 1, 2));
testCases.add(new DoubleToFractionTestCase(1d / 3d, 1, 3));
@@ -210,7 +210,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<UnaryOperatorTestCase> collectAbsTestCases() {
- List<UnaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new UnaryOperatorTestCase(10, 21, 10, 21));
testCases.add(new UnaryOperatorTestCase(-11, 23, 11, 23));
@@ -227,7 +227,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<UnaryOperatorTestCase> collectReciprocalTestCases() {
- List<UnaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new UnaryOperatorTestCase(50, 75, 3, 2));
testCases.add(new UnaryOperatorTestCase(4, 3, 3, 4));
@@ -243,7 +243,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<UnaryOperatorTestCase> collectNegateTestCases() {
- List<UnaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<UnaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new UnaryOperatorTestCase(50, 75, -2, 3));
testCases.add(new UnaryOperatorTestCase(-50, 75, 2, 3));
@@ -266,7 +266,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryOperatorTestCase> collectAddFractionTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 1));
testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 7, 6));
@@ -316,7 +316,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryIntOperatorTestCase> collectAddIntTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(1, 3, 0, 1, 3));
testCases.add(new BinaryIntOperatorTestCase(-1, 3, 0, -1, 3));
@@ -334,7 +334,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryOperatorTestCase> collectDivideByFractionTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 1));
testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 3, 4));
@@ -366,7 +366,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryIntOperatorTestCase> collectDivideByIntTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
testCases.add(new BinaryIntOperatorTestCase(0, 5, 11, 0, 1));
@@ -384,7 +384,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryOperatorTestCase> collectMultiplyByFractionTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 1, 4));
testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, 1, 3));
@@ -409,7 +409,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryIntOperatorTestCase> collectMultiplyByIntTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
testCases.add(new BinaryIntOperatorTestCase(6, 35, 15, 18, 7));
@@ -430,7 +430,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryOperatorTestCase> collectSubtractFractionTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, 2, 1, 2, 0, 1));
testCases.add(new BinaryOperatorTestCase(1, 2, 2, 3, -1, 6));
@@ -469,7 +469,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryIntOperatorTestCase> collectSubtractIntTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, -2, 3));
testCases.add(new BinaryIntOperatorTestCase(0, 1, 3, -3, 1));
@@ -486,7 +486,7 @@ final class CommonTestCases {
* @return a list of test cases as described above
*/
private static List<BinaryIntOperatorTestCase> collectPowTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(3, 7, 0, 1, 1));
testCases.add(new BinaryIntOperatorTestCase(3, 7, 1, 3, 7));
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 04ac063..798d6fb 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -44,13 +44,13 @@ public class FractionTest {
}
private static void assertDoubleValue(double expected, int numerator, int denominator) {
- Fraction f = Fraction.of(numerator, denominator);
+ final Fraction f = Fraction.of(numerator, denominator);
Assertions.assertEquals(expected, f.doubleValue());
}
@Test
public void testConstructor() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
assertFraction(
testCase.expectedNumerator,
testCase.expectedDenominator,
@@ -81,7 +81,7 @@ public class FractionTest {
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
- for (CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleConstructorTestCases()) {
+ for (final CommonTestCases.DoubleToFractionTestCase testCase : CommonTestCases.doubleConstructorTestCases()) {
assertFraction(
testCase.expectedNumerator,
testCase.expectedDenominator,
@@ -193,8 +193,8 @@ public class FractionTest {
// these two values are different approximations of PI
// the first one is approximately PI - 3.07e-18
// the second one is approximately PI + 1.936e-17
- Fraction pi1 = Fraction.of(1068966896, 340262731);
- Fraction pi2 = Fraction.of(411557987, 131002976);
+ final Fraction pi1 = Fraction.of(1068966896, 340262731);
+ final Fraction pi2 = Fraction.of(411557987, 131002976);
Assertions.assertEquals(-1, pi1.compareTo(pi2));
Assertions.assertEquals(1, pi2.compareTo(pi1));
Assertions.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
@@ -266,16 +266,16 @@ public class FractionTest {
@Test
public void testAbs() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
- Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
+ final Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.abs());
}
}
@Test
public void testReciprocal() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
- Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
+ final Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.reciprocal());
}
@@ -285,8 +285,8 @@ public class FractionTest {
@Test
public void testNegate() {
- for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.negateTestCases()) {
- Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
+ for (final CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.negateTestCases()) {
+ final Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.negate());
}
@@ -300,24 +300,24 @@ public class FractionTest {
@Test
public void testAdd() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.addFractionTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.addFractionTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
}
- for (CommonTestCases.BinaryOperatorTestCase testCase : addFractionOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : addFractionOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
Assertions.assertThrows(ArithmeticException.class, () -> f1.add(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : addIntOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : addIntOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
Assertions.assertThrows(ArithmeticException.class, () -> f1.add(i2));
}
@@ -331,24 +331,24 @@ public class FractionTest {
@Test
public void testDivide() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.divideByFractionTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.divideByFractionTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
}
- for (CommonTestCases.BinaryOperatorTestCase testCase : divideByFractionOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : divideByFractionOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
Assertions.assertThrows(ArithmeticException.class, () -> f1.divide(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : divideByIntOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : divideByIntOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
Assertions.assertThrows(ArithmeticException.class, () -> f1.divide(i2));
}
@@ -360,24 +360,24 @@ public class FractionTest {
@Test
public void testMultiply() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.multiplyByFractionTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.multiplyByFractionTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
}
- for (CommonTestCases.BinaryOperatorTestCase testCase : multiplyByFractionOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : multiplyByFractionOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
Assertions.assertThrows(ArithmeticException.class, () -> f1.multiply(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : multiplyByIntOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : multiplyByIntOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
Assertions.assertThrows(ArithmeticException.class, () -> f1.multiply(i2));
}
@@ -386,9 +386,9 @@ public class FractionTest {
@Test
public void testPow() {
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int exponent = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int exponent = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
}
@@ -400,24 +400,24 @@ public class FractionTest {
@Test
public void testSubtract() {
- for (CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.subtractFractionTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : CommonTestCases.subtractFractionTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
}
- for (CommonTestCases.BinaryOperatorTestCase testCase : subtractFractionOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ for (final CommonTestCases.BinaryOperatorTestCase testCase : subtractFractionOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
Assertions.assertThrows(ArithmeticException.class, () -> f1.subtract(f2));
}
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : subtractIntOverflowTestCases()) {
- Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int i2 = testCase.secondOperand;
+ for (final CommonTestCases.BinaryIntOperatorTestCase testCase : subtractIntOverflowTestCases()) {
+ final Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ final int i2 = testCase.secondOperand;
Assertions.assertThrows(ArithmeticException.class, () -> f1.subtract(i2));
}
@@ -431,24 +431,24 @@ public class FractionTest {
@Test
public void testEqualsAndHashCode() {
- Fraction zero = Fraction.of(0, 1);
+ final Fraction zero = Fraction.of(0, 1);
Assertions.assertEquals(zero, zero);
Assertions.assertNotEquals(zero, null);
Assertions.assertFalse(zero.equals(new Object()));
Assertions.assertFalse(zero.equals(Double.valueOf(0)));
// Equal to same rational number
- Fraction zero2 = Fraction.of(0, 2);
+ final Fraction zero2 = Fraction.of(0, 2);
assertEqualAndHashCodeEqual(zero, zero2);
// Not equal to different rational number
- Fraction one = Fraction.of(1, 1);
+ final Fraction one = Fraction.of(1, 1);
Assertions.assertNotEquals(zero, one);
Assertions.assertNotEquals(one, zero);
// Test using different representations of the same fraction
// (Denominators are primes)
- for (int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}, {0, 3}}) {
+ for (final int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}, {0, 3}}) {
final int num = f[0];
final int den = f[1];
Fraction f1 = Fraction.of(-num, den);
@@ -462,19 +462,19 @@ public class FractionTest {
}
// Same numerator or denominator as 1/1
- Fraction half = Fraction.of(1, 2);
- Fraction two = Fraction.of(2, 1);
+ final Fraction half = Fraction.of(1, 2);
+ final Fraction two = Fraction.of(2, 1);
Assertions.assertNotEquals(one, half);
Assertions.assertNotEquals(one, two);
// Check worst case fractions which will have a component using MIN_VALUE.
// Note: abs(MIN_VALUE) is negative but this should not effect the equals result.
- Fraction almostOne = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- Fraction almostOne2 = Fraction.of(Integer.MIN_VALUE, -Integer.MAX_VALUE);
+ final Fraction almostOne = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ final Fraction almostOne2 = Fraction.of(Integer.MIN_VALUE, -Integer.MAX_VALUE);
Assertions.assertEquals(almostOne, almostOne);
Assertions.assertNotEquals(almostOne, almostOne2);
- Fraction almostZero = Fraction.of(-1, Integer.MIN_VALUE);
- Fraction almostZero2 = Fraction.of(1, Integer.MIN_VALUE);
+ final Fraction almostZero = Fraction.of(-1, Integer.MIN_VALUE);
+ final Fraction almostZero2 = Fraction.of(1, Integer.MIN_VALUE);
Assertions.assertEquals(almostZero, almostZero);
Assertions.assertNotEquals(almostZero, almostZero2);
}
@@ -514,12 +514,12 @@ public class FractionTest {
@Test
public void testSerial() {
- Fraction[] fractions = {
+ final Fraction[] fractions = {
Fraction.of(3, 4), Fraction.ONE, Fraction.ZERO,
Fraction.of(17), Fraction.from(Math.PI, 1000),
Fraction.of(-5, 2)
};
- for (Fraction fraction : fractions) {
+ for (final Fraction fraction : fractions) {
Assertions.assertEquals(fraction,
TestUtils.serializeAndRecover(fraction));
}
@@ -537,7 +537,7 @@ public class FractionTest {
@Test
public void testParse() {
- String[] validExpressions = new String[] {
+ final String[] validExpressions = new String[] {
"1 / 2",
"-1 / 2",
"1 / -2",
@@ -553,7 +553,7 @@ public class FractionTest {
"-3",
"-3"
};
- Fraction[] fractions = {
+ final Fraction[] fractions = {
Fraction.of(1, 2),
Fraction.of(-1, 2),
Fraction.of(1, -2),
@@ -570,7 +570,7 @@ public class FractionTest {
Fraction.of(3, -1),
};
int inc = 0;
- for (Fraction fraction : fractions) {
+ for (final Fraction fraction : fractions) {
Assertions.assertEquals(fraction,
Fraction.parse(validExpressions[inc]));
inc++;
@@ -596,7 +596,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryOperatorTestCase> addFractionOverflowTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 5, -1, 5, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, -1, 1, 0, 0));
@@ -611,7 +611,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryIntOperatorTestCase> addIntOverflowTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, -1, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, 1, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(1, 2, Integer.MIN_VALUE / -2, 0, 0));
@@ -623,7 +623,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryOperatorTestCase> divideByFractionOverflowTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 2, 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, -2, 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(1, Integer.MIN_VALUE, 2, 1, 0, 0));
@@ -636,7 +636,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryIntOperatorTestCase> divideByIntOverflowTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(1, Integer.MAX_VALUE, 2, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(1, Integer.MAX_VALUE, -2, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(1, Integer.MIN_VALUE, 2, 0, 0));
@@ -649,7 +649,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryOperatorTestCase> multiplyByFractionOverflowTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, 2, 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, -2, 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, 2, 1, 0, 0));
@@ -662,7 +662,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryIntOperatorTestCase> multiplyByIntOverflowTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, 2, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, -2, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, 2, 0, 0));
@@ -675,7 +675,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryOperatorTestCase> subtractFractionOverflowTestCases() {
- List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 1, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 5, 1, 5, 0, 0));
testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, 1, 1, 0, 0));
@@ -690,7 +690,7 @@ public class FractionTest {
* @return a list of test cases
*/
private static List<BinaryIntOperatorTestCase> subtractIntOverflowTestCases() {
- List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ final List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, 1, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, -1, 0, 0));
testCases.add(new BinaryIntOperatorTestCase(1, 2, Integer.MIN_VALUE / 2, 0, 0));
[commons-numbers] 25/26: Add integer case to double constructor
test cases.
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 466d33e9b9028740ed3b4e9259f4423e8fc4750b
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 22:40:21 2020 +0100
Add integer case to double constructor test cases.
---
.../test/java/org/apache/commons/numbers/fraction/CommonTestCases.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index b0f703f..59bd68e 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -198,6 +198,7 @@ final class CommonTestCases {
testCases.add(new DoubleToFractionTestCase(0.00000000000001, 0, 1));
testCases.add(new DoubleToFractionTestCase(0.40000000000001, 2, 5));
testCases.add(new DoubleToFractionTestCase(15.0000000000001, 15, 1));
+ testCases.add(new DoubleToFractionTestCase(15.0, 15, 1));
testCases.add(new DoubleToFractionTestCase(0.0, 0, 1));
testCases.add(new DoubleToFractionTestCase(-0.0, 0, 1));
[commons-numbers] 06/26: BigFraction: Remove pow(long/BigInteger)
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 51419db92c6fa1edd7b2d2cfaf26ae6bd4f45704
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Apr 13 21:09:39 2020 +0100
BigFraction: Remove pow(long/BigInteger)
These are currently redundant given the maximum supported range of
BigInteger in the reference JDK.
---
.../commons/numbers/fraction/BigFraction.java | 52 ++--------------------
.../commons/numbers/fraction/BigFractionTest.java | 2 -
2 files changed, 4 insertions(+), 50 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index d293252..a72cdb1 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -21,7 +21,6 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Objects;
-import org.apache.commons.numbers.core.ArithmeticUtils;
import org.apache.commons.numbers.core.NativeOperators;
/**
@@ -899,6 +898,10 @@ public final class BigFraction
return this;
}
+ // Note: Raise the BigIntegers to the power and then reduce.
+ // The supported range for BigInteger is currently
+ // +/-2^(Integer.MAX_VALUE) exclusive thus larger
+ // exponents (long, BigInteger) are currently not supported.
if (exponent < 0) {
return new BigFraction(denominator.pow(-exponent),
numerator.pow(-exponent));
@@ -908,53 +911,6 @@ public final class BigFraction
}
/**
- * Returns a {@code BigFraction} whose value is
- * <code>this<sup>exponent</sup></code>, returning the result in reduced form.
- *
- * @param exponent exponent to which this {@code BigFraction} is to be raised.
- * @return <code>this<sup>exponent</sup></code>.
- */
- public BigFraction pow(final long exponent) {
- if (exponent == 0) {
- return ONE;
- }
- if (isZero()) {
- return this;
- }
-
- if (exponent < 0) {
- return new BigFraction(ArithmeticUtils.pow(denominator, -exponent),
- ArithmeticUtils.pow(numerator, -exponent));
- }
- return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
- ArithmeticUtils.pow(denominator, exponent));
- }
-
- /**
- * Returns a {@code BigFraction} whose value is
- * <code>this<sup>exponent</sup></code>, returning the result in reduced form.
- *
- * @param exponent exponent to which this {@code BigFraction} is to be raised.
- * @return <code>this<sup>exponent</sup></code>.
- */
- public BigFraction pow(final BigInteger exponent) {
- if (exponent.signum() == 0) {
- return ONE;
- }
- if (isZero()) {
- return this;
- }
-
- if (exponent.signum() == -1) {
- final BigInteger eNeg = exponent.negate();
- return new BigFraction(ArithmeticUtils.pow(denominator, eNeg),
- ArithmeticUtils.pow(numerator, eNeg));
- }
- return new BigFraction(ArithmeticUtils.pow(numerator, exponent),
- ArithmeticUtils.pow(denominator, exponent));
- }
-
- /**
* Returns the {@code String} representing this fraction.
* Uses:
* <ul>
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 33445a4..a1e53e0 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -556,8 +556,6 @@ public class BigFractionTest {
BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
int exponent = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
- assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow((long) exponent));
- assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(BigInteger.valueOf(exponent)));
}
// Note: BigInteger magnitude is limited to 2^Integer.MAX_VALUE exclusive
[commons-numbers] 24/26: Fraction: Add tests for Integer.MIN_VALUE
in intValue()
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit ccd5e31a6cf67cc061a4f53abc3920492e3ce5b5
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 22:10:46 2020 +0100
Fraction: Add tests for Integer.MIN_VALUE in intValue()
The intValue cannot be done by simple integer divide arithmetic:
numerator / denominator
This will return Integer.MIN_VALUE for the fraction Integer.MIN_VALUE /
-1. The correct result is Integer.MAX_VALUE (as the fraction is
positive).
integer divide arithmetic can be used in longValue().
---
.../java/org/apache/commons/numbers/fraction/Fraction.java | 6 ++++--
.../java/org/apache/commons/numbers/fraction/FractionTest.java | 10 ++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index e9b7199..8a23872 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -444,7 +444,7 @@ public final class Fraction
* Returns the {@code float} value closest to this fraction.
* This calculates the fraction as numerator divided by denominator.
*
- * @return the fraction as {@code float}.
+ * @return the fraction as a {@code float}.
*/
@Override
public float floatValue() {
@@ -458,6 +458,8 @@ public final class Fraction
*/
@Override
public int intValue() {
+ // Note: numerator / denominator fails for Integer.MIN_VALUE / -1.
+ // Casting the double value handles this case.
return (int) doubleValue();
}
@@ -468,7 +470,7 @@ public final class Fraction
*/
@Override
public long longValue() {
- return (long) doubleValue();
+ return (long) numerator / denominator;
}
/**
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 798d6fb..80628fa 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -244,6 +244,11 @@ public class FractionTest {
Assertions.assertEquals(-1, Fraction.of(-3, 2).intValue());
Assertions.assertEquals(-1, Fraction.of(3, -2).intValue());
+ Assertions.assertEquals(0, Fraction.of(1, Integer.MIN_VALUE).intValue());
+ Assertions.assertEquals(0, Fraction.of(-1, Integer.MIN_VALUE).intValue());
+ Assertions.assertEquals(Integer.MIN_VALUE, Fraction.of(Integer.MIN_VALUE, 1).intValue());
+ Assertions.assertEquals(Integer.MAX_VALUE, Fraction.of(Integer.MIN_VALUE, -1).intValue());
+
Assertions.assertEquals(0, ZERO_P.intValue());
Assertions.assertEquals(0, ZERO_N.intValue());
}
@@ -260,6 +265,11 @@ public class FractionTest {
Assertions.assertEquals(-1L, Fraction.of(-3, 2).longValue());
Assertions.assertEquals(-1L, Fraction.of(3, -2).longValue());
+ Assertions.assertEquals(0, Fraction.of(1, Integer.MIN_VALUE).longValue());
+ Assertions.assertEquals(0, Fraction.of(-1, Integer.MIN_VALUE).longValue());
+ Assertions.assertEquals(Integer.MIN_VALUE, Fraction.of(Integer.MIN_VALUE, 1).longValue());
+ Assertions.assertEquals(Integer.MAX_VALUE + 1L, Fraction.of(Integer.MIN_VALUE, -1).longValue());
+
Assertions.assertEquals(0L, ZERO_P.longValue());
Assertions.assertEquals(0L, ZERO_N.longValue());
}
[commons-numbers] 15/26: Clean-up numbers core TestUtilities.
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit b47f05ebe6d298bc933603d1115602d3b96d91dc
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:11:05 2020 +0100
Clean-up numbers core TestUtilities.
Removed all public methods that are not used.
---
.../org/apache/commons/numbers/core/TestUtils.java | 143 +--------------------
1 file changed, 6 insertions(+), 137 deletions(-)
diff --git a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/TestUtils.java b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/TestUtils.java
index bfdb434..742de25 100644
--- a/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/TestUtils.java
+++ b/commons-numbers-core/src/test/java/org/apache/commons/numbers/core/TestUtils.java
@@ -23,11 +23,8 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import org.junit.jupiter.api.Assertions;
-
/**
* Test utilities.
- * TODO: Cleanup (remove unused and obsolete methods).
*/
public final class TestUtils {
/**
@@ -47,148 +44,20 @@ public final class TestUtils {
public static Object serializeAndRecover(Object o) {
try {
// serialize the Object
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ObjectOutputStream so = new ObjectOutputStream(bos);
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final ObjectOutputStream so = new ObjectOutputStream(bos);
so.writeObject(o);
// deserialize the Object
- ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
- ObjectInputStream si = new ObjectInputStream(bis);
+ final ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ final ObjectInputStream si = new ObjectInputStream(bis);
return si.readObject();
- } catch (IOException ioe) {
+ } catch (final IOException ioe) {
return null;
- } catch (ClassNotFoundException cnfe) {
+ } catch (final ClassNotFoundException cnfe) {
return null;
}
}
-
- /**
- * Verifies that serialization preserves equals and hashCode.
- * Serializes the object, then recovers it and checks equals and hash code.
- *
- * @param object the object to serialize and recover
- */
- public static void checkSerializedEquality(Object object) {
- Object object2 = serializeAndRecover(object);
- Assertions.assertEquals(object, object2, "Equals check");
- Assertions.assertEquals(object.hashCode(), object2.hashCode(), "HashCode check");
- }
-
- /**
- * Verifies that the relative error in actual vs. expected is less than or
- * equal to relativeError. If expected is infinite or NaN, actual must be
- * the same (NaN or infinity of the same sign).
- *
- * @param expected expected value
- * @param actual observed value
- * @param relativeError maximum allowable relative error
- */
- public static void assertRelativelyEquals(double expected, double actual,
- double relativeError) {
- assertRelativelyEquals(null, expected, actual, relativeError);
- }
-
- /**
- * Verifies that the relative error in actual vs. expected is less than or
- * equal to relativeError. If expected is infinite or NaN, actual must be
- * the same (NaN or infinity of the same sign).
- *
- * @param msg message to return with failure
- * @param expected expected value
- * @param actual observed value
- * @param relativeError maximum allowable relative error
- */
- public static void assertRelativelyEquals(String msg, double expected,
- double actual, double relativeError) {
- if (Double.isNaN(expected)) {
- Assertions.assertTrue(Double.isNaN(actual), msg);
- } else if (Double.isNaN(actual)) {
- Assertions.assertTrue(Double.isNaN(expected), msg);
- } else if (Double.isInfinite(actual) || Double.isInfinite(expected)) {
- Assertions.assertEquals(expected, actual, relativeError);
- } else if (expected == 0.0) {
- Assertions.assertEquals(expected, actual, relativeError, msg);
- } else {
- double absError = Math.abs(expected) * relativeError;
- Assertions.assertEquals(expected, actual, absError, msg);
- }
- }
-
- /**
- * Fails iff values does not contain a number within epsilon of x.
- *
- * @param msg message to return with failure
- * @param values double array to search
- * @param x value sought
- * @param epsilon tolerance
- */
- public static void assertContains(String msg, double[] values,
- double x, double epsilon) {
- for (double value : values) {
- if (Precision.equals(value, x, epsilon)) {
- return;
- }
- }
- Assertions.fail(msg + " Unable to find " + x);
- }
-
- /**
- * Fails iff values does not contain a number within epsilon of x.
- *
- * @param values double array to search
- * @param x value sought
- * @param epsilon tolerance
- */
- public static void assertContains(double[] values, double x,
- double epsilon) {
- assertContains(null, values, x, epsilon);
- }
-
- /**
- * Updates observed counts of values in quartiles.
- * counts[0] <-> 1st quartile ... counts[3] <-> top quartile
- */
- public static void updateCounts(double value, long[] counts, double[] quartiles) {
- if (value < quartiles[0]) {
- counts[0]++;
- } else if (value > quartiles[2]) {
- counts[3]++;
- } else if (value > quartiles[1]) {
- counts[2]++;
- } else {
- counts[1]++;
- }
- }
-
- /**
- * Eliminates points with zero mass from densityPoints and densityValues parallel
- * arrays. Returns the number of positive mass points and collapses the arrays so
- * that the first <returned value> elements of the input arrays represent the positive
- * mass points.
- */
- public static int eliminateZeroMassPoints(int[] densityPoints, double[] densityValues) {
- int positiveMassCount = 0;
- for (int i = 0; i < densityValues.length; i++) {
- if (densityValues[i] > 0) {
- positiveMassCount++;
- }
- }
- if (positiveMassCount < densityValues.length) {
- int[] newPoints = new int[positiveMassCount];
- double[] newValues = new double[positiveMassCount];
- int j = 0;
- for (int i = 0; i < densityValues.length; i++) {
- if (densityValues[i] > 0) {
- newPoints[j] = densityPoints[i];
- newValues[j] = densityValues[i];
- j++;
- }
- }
- System.arraycopy(newPoints, 0, densityPoints, 0, positiveMassCount);
- System.arraycopy(newValues, 0, densityValues, 0, positiveMassCount);
- }
- return positiveMassCount;
- }
}
[commons-numbers] 26/26: Fraction: double constructor to avoid
iterations <= epsilon.
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 69f7ddc5065961e12b63002d2d4a34b145758963
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 22:45:31 2020 +0100
Fraction: double constructor to avoid iterations <= epsilon.
Change < epsilon to <= epsilon.
The rest of the double constructor logic uses > epsilon. Thus <= epsilon
is the opposite comparison operator.
This allows avoiding the iterations in max denominator mode (epsilon ==
0.0) when the double argument is an exact integer.
---
.../src/main/java/org/apache/commons/numbers/fraction/BigFraction.java | 2 +-
.../src/main/java/org/apache/commons/numbers/fraction/Fraction.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 8e0a8cb..d71c1db 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -152,7 +152,7 @@ public final class BigFraction
// check for (almost) integer arguments, which should not go
// to iterations.
- if (Math.abs(a0 - value) < epsilon) {
+ if (Math.abs(a0 - value) <= epsilon) {
return new BigFraction(BigInteger.valueOf(a0),
BigInteger.ONE);
}
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 8a23872..22e30c2 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -161,7 +161,7 @@ public final class Fraction
}
// check for (almost) integer arguments, which should not go to iterations.
- if (Math.abs(a0 - value) < epsilon) {
+ if (Math.abs(a0 - value) <= epsilon) {
this.numerator = (int) a0;
this.denominator = 1;
return;
[commons-numbers] 11/26: Fraction: efficient multiply by integer
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 4002f401de28135700526749664d4f52a012411f
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 00:16:18 2020 +0100
Fraction: efficient multiply by integer
---
.../main/java/org/apache/commons/numbers/fraction/Fraction.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index be42d68..5eb3beb 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -584,7 +584,7 @@ public final class Fraction
*
* @param value Value to multiply by.
* @return {@code this * value}.
- * @throws ArithmeticException if the resulting numerator or denominator
+ * @throws ArithmeticException if the resulting numerator
* cannot be represented in an {@code int}.
*/
@Override
@@ -592,7 +592,12 @@ public final class Fraction
if (value == 0 || isZero()) {
return ZERO;
}
- return multiply(of(value));
+
+ // knuth 4.5.1
+ // Make sure we don't overflow unless the result *must* overflow.
+ final int d2 = ArithmeticUtils.gcd(value, denominator);
+ return new Fraction(Math.multiplyExact(numerator, value / d2),
+ denominator / d2);
}
/**
[commons-numbers] 08/26: Fraction: fix compareTo for positive
numbers with two negative parts
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 854d141a9332c26b09c8164d6f428fb69d9f2fc3
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Apr 13 21:55:22 2020 +0100
Fraction: fix compareTo for positive numbers with two negative parts
The numerator and denominator can both be negative. Thus the comparison
by magnitude (when the signum is equal) must use the absolute values.
---
.../commons/numbers/fraction/BigFraction.java | 6 +++---
.../apache/commons/numbers/fraction/Fraction.java | 22 +++++++++++++++++-----
.../commons/numbers/fraction/BigFractionTest.java | 4 ++--
.../commons/numbers/fraction/FractionTest.java | 4 ++--
4 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index a72cdb1..1e60668 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -953,9 +953,9 @@ public final class BigFraction
if (lhsSigNum == 0) {
return 0;
}
- // Compare magnitude
- final BigInteger nOd = numerator.multiply(other.denominator);
- final BigInteger dOn = denominator.multiply(other.numerator);
+ // Compare absolute magnitude
+ final BigInteger nOd = numerator.abs().multiply(other.denominator.abs());
+ final BigInteger dOn = denominator.abs().multiply(other.numerator.abs());
return nOd.compareTo(dOn);
}
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 99151f5..5154eff 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -696,15 +696,27 @@ public final class Fraction
*/
@Override
public int compareTo(Fraction other) {
- final int lhsSigNum = signum();
- final int rhsSigNum = other.signum();
+ // Compute the sign of each part
+ final int lns = Integer.signum(numerator);
+ final int lds = Integer.signum(denominator);
+ final int rns = Integer.signum(other.numerator);
+ final int rds = Integer.signum(other.denominator);
+
+ final int lhsSigNum = lns * lds;
+ final int rhsSigNum = rns * rds;
if (lhsSigNum != rhsSigNum) {
return (lhsSigNum > rhsSigNum) ? 1 : -1;
}
- // Same sign: compare magnitude
- final long nOd = ((long) numerator) * other.denominator;
- final long dOn = ((long) denominator) * other.numerator;
+ // Same sign.
+ // Avoid a multiply if both fractions are zero
+ if (lhsSigNum == 0) {
+ return 0;
+ }
+ // Compare absolute magnitude.
+ // Multiplication by the signum is equal to the absolute.
+ final long nOd = ((long) numerator) * lns * other.denominator * rds;
+ final long dOn = ((long) denominator) * lds * other.numerator * rns;
return Long.compare(nOd, dOn);
}
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 777d0a9..bdc8003 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -211,9 +211,9 @@ public class BigFractionTest {
Assertions.assertEquals(0, f.compareTo(a));
Assertions.assertEquals(1, f.compareTo(e));
Assertions.assertEquals(-1, e.compareTo(f));
-// Assertions.assertEquals(-1, g.compareTo(a));
+ Assertions.assertEquals(-1, g.compareTo(a));
Assertions.assertEquals(-1, g.compareTo(f));
-// Assertions.assertEquals(1, a.compareTo(g));
+ Assertions.assertEquals(1, a.compareTo(g));
Assertions.assertEquals(-1, d.compareTo(g));
Assertions.assertEquals(0, BigFraction.of(0, 3).compareTo(BigFraction.of(0, -2)));
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 82fe803..7205c6b 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -170,9 +170,9 @@ public class FractionTest {
Assertions.assertEquals(0, f.compareTo(a));
Assertions.assertEquals(1, f.compareTo(e));
Assertions.assertEquals(-1, e.compareTo(f));
-// Assertions.assertEquals(-1, g.compareTo(a));
+ Assertions.assertEquals(-1, g.compareTo(a));
Assertions.assertEquals(-1, g.compareTo(f));
-// Assertions.assertEquals(1, a.compareTo(g));
+ Assertions.assertEquals(1, a.compareTo(g));
Assertions.assertEquals(-1, d.compareTo(g));
Assertions.assertEquals(0, Fraction.of(0, 3).compareTo(Fraction.of(0, -2)));
[commons-numbers] 17/26: Fraction: use factory constructor in
add/subtract
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 5192e10a101ebf7d91706b7ce1b5d4321d664a18
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:26:10 2020 +0100
Fraction: use factory constructor in add/subtract
These can create zero if the denominator is 1.
Added a case to the common test cases to check the canonical zero (0 /
1) is returned.
---
.../main/java/org/apache/commons/numbers/fraction/BigFraction.java | 6 ++----
.../src/main/java/org/apache/commons/numbers/fraction/Fraction.java | 6 ++----
.../java/org/apache/commons/numbers/fraction/CommonTestCases.java | 2 ++
3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 6e1ea48..8e0a8cb 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -682,8 +682,7 @@ public final class BigFraction
return of(value);
}
- // Direct constructor: cannot add an integer to a fraction to produce zero
- return new BigFraction(numerator.add(denominator.multiply(value)), denominator);
+ return of(numerator.add(denominator.multiply(value)), denominator);
}
/**
@@ -757,8 +756,7 @@ public final class BigFraction
return of(value.negate());
}
- // Direct constructor: cannot subtract an integer from a fraction to produce zero
- return new BigFraction(numerator.subtract(denominator.multiply(value)), denominator);
+ return of(numerator.subtract(denominator.multiply(value)), denominator);
}
/**
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 6702950..ce6954b 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -481,8 +481,7 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction add(final int value) {
- // Direct constructor: cannot add an integer to a fraction to produce zero
- return new Fraction(numerator + value * denominator, denominator);
+ return of(numerator + value * denominator, denominator);
}
/**
@@ -509,8 +508,7 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction subtract(final int value) {
- // Direct constructor: cannot subtract an integer from a fraction to produce zero
- return new Fraction(numerator - value * denominator, denominator);
+ return of(numerator - value * denominator, denominator);
}
/**
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index 5f7c9e7..c582de5 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -322,6 +322,7 @@ final class CommonTestCases {
testCases.add(new BinaryIntOperatorTestCase(-1, 3, 0, -1, 3));
testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 4, 3));
testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, -2, 3));
+ testCases.add(new BinaryIntOperatorTestCase(2, -1, 2, 0, 1));
testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE - 1, 1, 1, Integer.MAX_VALUE, 1));
return testCases;
@@ -474,6 +475,7 @@ final class CommonTestCases {
testCases.add(new BinaryIntOperatorTestCase(0, 1, 3, -3, 1));
testCases.add(new BinaryIntOperatorTestCase(2, 3, 3, -7, 3));
testCases.add(new BinaryIntOperatorTestCase(2, 3, 0, 2, 3));
+ testCases.add(new BinaryIntOperatorTestCase(2, -1, -2, 0, 1));
return testCases;
}
[commons-numbers] 03/26: Fixed Fraction.compareTo
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 36154bba47e78c3a3d1ff9193ffacb89be13c63f
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Apr 12 21:29:27 2020 +0100
Fixed Fraction.compareTo
Since the sign can be in the numerator or denominator the signum must be
checked first before the magnitude can be tested.
---
.../org/apache/commons/numbers/fraction/BigFraction.java | 4 +++-
.../java/org/apache/commons/numbers/fraction/Fraction.java | 12 ++++++++++--
.../org/apache/commons/numbers/fraction/FractionTest.java | 4 ++--
3 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 0d145fb..d293252 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -992,10 +992,12 @@ public final class BigFraction
if (lhsSigNum != rhsSigNum) {
return (lhsSigNum > rhsSigNum) ? 1 : -1;
}
+ // Same sign.
+ // Avoid a multiply if both fractions are zero
if (lhsSigNum == 0) {
return 0;
}
-
+ // Compare magnitude
final BigInteger nOd = numerator.multiply(other.denominator);
final BigInteger dOn = denominator.multiply(other.numerator);
return nOd.compareTo(dOn);
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index c5a883d..99151f5 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -696,8 +696,16 @@ public final class Fraction
*/
@Override
public int compareTo(Fraction other) {
- return Long.compare(((long) numerator) * other.denominator,
- ((long) denominator) * other.numerator);
+ final int lhsSigNum = signum();
+ final int rhsSigNum = other.signum();
+
+ if (lhsSigNum != rhsSigNum) {
+ return (lhsSigNum > rhsSigNum) ? 1 : -1;
+ }
+ // Same sign: compare magnitude
+ final long nOd = ((long) numerator) * other.denominator;
+ final long dOn = ((long) denominator) * other.numerator;
+ return Long.compare(nOd, dOn);
}
/**
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index d1916f6..584c28f 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -153,8 +153,8 @@ public class FractionTest {
Assertions.assertEquals(-1, b.compareTo(a));
Assertions.assertEquals(-1, d.compareTo(a));
Assertions.assertEquals(1, a.compareTo(d));
-// Assertions.assertEquals(-1, e.compareTo(a));
-// Assertions.assertEquals(1, a.compareTo(e));
+ Assertions.assertEquals(-1, e.compareTo(a));
+ Assertions.assertEquals(1, a.compareTo(e));
Assertions.assertEquals(0, d.compareTo(e));
Assertions.assertEquals(0, Fraction.of(0, 3).compareTo(Fraction.of(0, -2)));
[commons-numbers] 05/26: Fraction: Increase similarity between
BigFraction tests
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit bb645f6c19a93cf2bc8aef21ee1c09e0bab3658d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Apr 13 21:01:30 2020 +0100
Fraction: Increase similarity between BigFraction tests
Adds some compareTo tests that currently fail.
---
.../commons/numbers/fraction/BigFractionTest.java | 87 +++++++++++-----------
.../commons/numbers/fraction/CommonTestCases.java | 3 +
.../commons/numbers/fraction/FractionTest.java | 50 +++++++------
3 files changed, 73 insertions(+), 67 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 3a24a20..33445a4 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -99,16 +99,31 @@ public class BigFractionTest {
);
}
+ // Cases with different exact results from Fraction
+ assertFraction(6004799503160661L, 18014398509481984L, BigFraction.from(1.0 / 3.0));
+ assertFraction(6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / 100.0));
+ assertFraction(1784551352345559L, 562949953421312L, BigFraction.from(317.0 / 100.0));
+ assertFraction(-6004799503160661L, 18014398509481984L, BigFraction.from(-1.0 / 3.0));
+ assertFraction(-6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / -100.0));
+ assertFraction(-1784551352345559L, 562949953421312L, BigFraction.from(-317.0 / 100.0));
+
+ // Extreme double values
+ Assertions.assertEquals(1L, BigFraction.from(Double.MAX_VALUE).getDenominatorAsLong());
+ Assertions.assertEquals(1L, BigFraction.from(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong());
+ assertFraction(BigInteger.ONE, BigInteger.ONE.shiftLeft(1074), BigFraction.from(Double.MIN_VALUE));
+
+ // Check exact round-trip of double
Assertions.assertEquals(0.00000000000001, BigFraction.from(0.00000000000001).doubleValue());
Assertions.assertEquals(0.40000000000001, BigFraction.from(0.40000000000001).doubleValue());
Assertions.assertEquals(15.0000000000001, BigFraction.from(15.0000000000001).doubleValue());
+ // Check the representation
assertFraction(3602879701896487L, 9007199254740992L, BigFraction.from(0.40000000000001));
assertFraction(1055531162664967L, 70368744177664L, BigFraction.from(15.0000000000001));
}
// MATH-181
@Test
- public void testDigitLimitConstructor() throws Exception {
+ public void testDoubleConstructorWithMaxDenominator() throws Exception {
assertFraction(2, 5, BigFraction.from(0.4, 9));
assertFraction(2, 5, BigFraction.from(0.4, 99));
assertFraction(2, 5, BigFraction.from(0.4, 999));
@@ -144,22 +159,17 @@ public class BigFractionTest {
// MATH-1029
@Test
- public void testPositiveValueOverflow() {
+ public void testDoubleConstructorWithMaxDenominatorOverFlow() {
Assertions.assertThrows(ArithmeticException.class,
() -> BigFraction.from(1e10, 1000)
);
- }
-
- // MATH-1029
- @Test
- public void testNegativeValueOverflow() {
Assertions.assertThrows(ArithmeticException.class,
- () -> assertFraction((long) -1e10, 1, BigFraction.from(-1e10, 1000))
+ () -> BigFraction.from(-1e10, 1000)
);
}
@Test
- public void testEpsilonLimitConstructor() throws Exception {
+ public void testDoubleConstructorWithEpsilonLimit() throws Exception {
assertFraction(2, 5, BigFraction.from(0.4, 1.0e-5, 100));
assertFraction(3, 5, BigFraction.from(0.6152, 0.02, 100));
@@ -177,6 +187,8 @@ public class BigFractionTest {
final BigFraction c = BigFraction.of(1, 2);
final BigFraction d = BigFraction.of(-1, 2);
final BigFraction e = BigFraction.of(1, -2);
+ final BigFraction f = BigFraction.of(-1, -2);
+ final BigFraction g = BigFraction.of(-1, Integer.MIN_VALUE);
Assertions.assertEquals(0, a.compareTo(a));
Assertions.assertEquals(0, a.compareTo(c));
@@ -187,6 +199,14 @@ public class BigFractionTest {
Assertions.assertEquals(-1, e.compareTo(a));
Assertions.assertEquals(1, a.compareTo(e));
Assertions.assertEquals(0, d.compareTo(e));
+ Assertions.assertEquals(0, a.compareTo(f));
+ Assertions.assertEquals(0, f.compareTo(a));
+ Assertions.assertEquals(1, f.compareTo(e));
+ Assertions.assertEquals(-1, e.compareTo(f));
+// Assertions.assertEquals(-1, g.compareTo(a));
+ Assertions.assertEquals(-1, g.compareTo(f));
+// Assertions.assertEquals(1, a.compareTo(g));
+ Assertions.assertEquals(-1, d.compareTo(g));
Assertions.assertEquals(0, BigFraction.of(0, 3).compareTo(BigFraction.of(0, -2)));
@@ -411,22 +431,11 @@ public class BigFractionTest {
}
@Test
- public void testConstructorDouble() {
- assertFraction(0, 1, BigFraction.from(0.0));
- assertFraction(1, 2, BigFraction.from(0.5));
- assertFraction(6004799503160661L, 18014398509481984L, BigFraction.from(1.0 / 3.0));
- assertFraction(6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / 100.0));
- assertFraction(1784551352345559L, 562949953421312L, BigFraction.from(317.0 / 100.0));
- assertFraction(-1, 2, BigFraction.from(-0.5));
- assertFraction(-6004799503160661L, 18014398509481984L, BigFraction.from(-1.0 / 3.0));
- assertFraction(-6124895493223875L, 36028797018963968L, BigFraction.from(17.0 / -100.0));
- assertFraction(-1784551352345559L, 562949953421312L, BigFraction.from(-317.0 / 100.0));
- for (double v : new double[] {Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
- Assertions.assertThrows(IllegalArgumentException.class, () -> BigFraction.from(v));
- }
- Assertions.assertEquals(1L, BigFraction.from(Double.MAX_VALUE).getDenominatorAsLong());
- Assertions.assertEquals(1L, BigFraction.from(Double.longBitsToDouble(0x0010000000000000L)).getNumeratorAsLong());
- assertFraction(BigInteger.ONE, BigInteger.ONE.shiftLeft(1074), BigFraction.from(Double.MIN_VALUE));
+ public void testBigDecimalValue() {
+ Assertions.assertEquals(new BigDecimal(0.5), BigFraction.of(1, 2).bigDecimalValue());
+ Assertions.assertEquals(new BigDecimal("0.0003"), BigFraction.of(3, 10000).bigDecimalValue());
+ Assertions.assertEquals(new BigDecimal("0"), BigFraction.of(1, 3).bigDecimalValue(RoundingMode.DOWN));
+ Assertions.assertEquals(new BigDecimal("0.333"), BigFraction.of(1, 3).bigDecimalValue(3, RoundingMode.DOWN));
}
@Test
@@ -581,14 +590,6 @@ public class BigFractionTest {
}
@Test
- public void testBigDecimalValue() {
- Assertions.assertEquals(new BigDecimal(0.5), BigFraction.of(1, 2).bigDecimalValue());
- Assertions.assertEquals(new BigDecimal("0.0003"), BigFraction.of(3, 10000).bigDecimalValue());
- Assertions.assertEquals(new BigDecimal("0"), BigFraction.of(1, 3).bigDecimalValue(RoundingMode.DOWN));
- Assertions.assertEquals(new BigDecimal("0.333"), BigFraction.of(1, 3).bigDecimalValue(3, RoundingMode.DOWN));
- }
-
- @Test
public void testEqualsAndHashCode() {
BigFraction zero = BigFraction.of(0, 1);
Assertions.assertEquals(zero, zero);
@@ -650,16 +651,6 @@ public class BigFractionTest {
}
@Test
- public void testMath340() {
- BigFraction fractionA = BigFraction.from(0.00131);
- BigFraction fractionB = BigFraction.from(.37).reciprocal();
- BigFraction errorResult = fractionA.multiply(fractionB);
- BigFraction correctResult = BigFraction.of(fractionA.getNumerator().multiply(fractionB.getNumerator()),
- fractionA.getDenominator().multiply(fractionB.getDenominator()));
- Assertions.assertEquals(correctResult, errorResult);
- }
-
- @Test
public void testAdditiveNeutral() {
Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.zero());
}
@@ -743,4 +734,14 @@ public class BigFractionTest {
Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("1 / --2"));
Assertions.assertThrows(NumberFormatException.class, () -> BigFraction.parse("x"));
}
+
+ @Test
+ public void testMath340() {
+ BigFraction fractionA = BigFraction.from(0.00131);
+ BigFraction fractionB = BigFraction.from(.37).reciprocal();
+ BigFraction errorResult = fractionA.multiply(fractionB);
+ BigFraction correctResult = BigFraction.of(fractionA.getNumerator().multiply(fractionB.getNumerator()),
+ fractionA.getDenominator().multiply(fractionB.getDenominator()));
+ Assertions.assertEquals(correctResult, errorResult);
+ }
}
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index 336add7..39ad560 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -170,6 +170,9 @@ final class CommonTestCases {
testCases.add(new DoubleToFractionTestCase(9d / 11d, 9, 11));
testCases.add(new DoubleToFractionTestCase(10d / 11d, 10, 11));
+ testCases.add(new DoubleToFractionTestCase(-1d / 2d, -1, 2));
+ testCases.add(new DoubleToFractionTestCase(-1d / 3d, -1, 3));
+
testCases.add(new DoubleToFractionTestCase(0.00000000000001, 0, 1));
testCases.add(new DoubleToFractionTestCase(0.40000000000001, 2, 5));
testCases.add(new DoubleToFractionTestCase(15.0000000000001, 15, 1));
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index fccf015..6188d55 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -75,11 +75,19 @@ public class FractionTest {
Fraction.from(testCase.operand)
);
}
+
+ // Cases with different exact results from BigFraction
+ assertFraction(1, 3, Fraction.from(1.0 / 3.0));
+ assertFraction(17, 100, Fraction.from(17.0 / 100.0));
+ assertFraction(317, 100, Fraction.from(317.0 / 100.0));
+ assertFraction(-1, 3, Fraction.from(-1.0 / 3.0));
+ assertFraction(-17, 100, Fraction.from(17.0 / -100.0));
+ assertFraction(-317, 100, Fraction.from(-317.0 / 100.0));
}
// MATH-181
@Test
- public void testDigitLimitConstructor() throws Exception {
+ public void testDoubleConstructorWithMaxDenominator() throws Exception {
assertFraction(2, 5, Fraction.from(0.4, 9));
assertFraction(2, 5, Fraction.from(0.4, 99));
assertFraction(2, 5, Fraction.from(0.4, 999));
@@ -114,21 +122,21 @@ public class FractionTest {
}
@Test
- public void testIntegerOverflow() {
- checkIntegerOverflow(0.75000000001455192);
- checkIntegerOverflow(1.0e10);
- checkIntegerOverflow(-1.0e10);
- checkIntegerOverflow(-43979.60679604749);
+ public void testDoubleConstructorOverflow() {
+ assertDoubleConstructorOverflow(0.75000000001455192);
+ assertDoubleConstructorOverflow(1.0e10);
+ assertDoubleConstructorOverflow(-1.0e10);
+ assertDoubleConstructorOverflow(-43979.60679604749);
}
- private void checkIntegerOverflow(final double a) {
+ private void assertDoubleConstructorOverflow(final double a) {
Assertions.assertThrows(ArithmeticException.class,
() -> Fraction.from(a, 1.0e-12, 1000)
);
}
@Test
- public void testEpsilonLimitConstructor() throws Exception {
+ public void testDoubleConstructorWithEpsilonLimit() throws Exception {
assertFraction(2, 5, Fraction.from(0.4, 1.0e-5, 100));
assertFraction(3, 5, Fraction.from(0.6152, 0.02, 100));
@@ -146,6 +154,8 @@ public class FractionTest {
final Fraction c = Fraction.of(1, 2);
final Fraction d = Fraction.of(-1, 2);
final Fraction e = Fraction.of(1, -2);
+ final Fraction f = Fraction.of(-1, -2);
+ final Fraction g = Fraction.of(-1, Integer.MIN_VALUE);
Assertions.assertEquals(0, a.compareTo(a));
Assertions.assertEquals(0, a.compareTo(c));
@@ -156,6 +166,14 @@ public class FractionTest {
Assertions.assertEquals(-1, e.compareTo(a));
Assertions.assertEquals(1, a.compareTo(e));
Assertions.assertEquals(0, d.compareTo(e));
+ Assertions.assertEquals(0, a.compareTo(f));
+ Assertions.assertEquals(0, f.compareTo(a));
+ Assertions.assertEquals(1, f.compareTo(e));
+ Assertions.assertEquals(-1, e.compareTo(f));
+// Assertions.assertEquals(-1, g.compareTo(a));
+ Assertions.assertEquals(-1, g.compareTo(f));
+// Assertions.assertEquals(1, a.compareTo(g));
+ Assertions.assertEquals(-1, d.compareTo(g));
Assertions.assertEquals(0, Fraction.of(0, 3).compareTo(Fraction.of(0, -2)));
@@ -234,22 +252,6 @@ public class FractionTest {
}
@Test
- public void testConstructorDouble() {
- assertFraction(0, 1, Fraction.from(0.0));
- assertFraction(1, 2, Fraction.from(0.5));
- assertFraction(1, 3, Fraction.from(1.0 / 3.0));
- assertFraction(17, 100, Fraction.from(17.0 / 100.0));
- assertFraction(317, 100, Fraction.from(317.0 / 100.0));
- assertFraction(-1, 2, Fraction.from(-0.5));
- assertFraction(-1, 3, Fraction.from(-1.0 / 3.0));
- assertFraction(-17, 100, Fraction.from(17.0 / -100.0));
- assertFraction(-317, 100, Fraction.from(-317.0 / 100.0));
- for (double v : new double[] {Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
- Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(v));
- }
- }
-
- @Test
public void testAbs() {
for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.absTestCases()) {
Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
[commons-numbers] 07/26: Fraction: common test cases for arithmetic
with an integer
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit bcdbb3f3531d80a4d366e91b629b802a94667c9e
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Apr 13 21:42:24 2020 +0100
Fraction: common test cases for arithmetic with an integer
add/subtract/multiply/divide using an int argument.
---
.../commons/numbers/fraction/BigFractionTest.java | 84 +++++------
.../commons/numbers/fraction/CommonTestCases.java | 157 ++++++++++++++++++++-
.../commons/numbers/fraction/FractionTest.java | 45 +++---
3 files changed, 214 insertions(+), 72 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index a1e53e0..777d0a9 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -35,9 +35,17 @@ public class BigFractionTest {
/** The zero representation with negative denominator. */
private static final BigFraction ZERO_N = BigFraction.of(0, -1);
+ private static void assertFraction(int expectedNumerator, int expectedDenominator, BigFraction actual) {
+ Assertions.assertEquals(expectedNumerator, actual.getNumeratorAsInt());
+ Assertions.assertEquals(expectedDenominator, actual.getDenominatorAsInt());
+ Assertions.assertEquals(
+ Integer.signum(expectedNumerator) * Integer.signum(expectedDenominator),
+ actual.signum());
+ }
+
private static void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
- Assertions.assertEquals(BigInteger.valueOf(expectedNumerator), actual.getNumerator());
- Assertions.assertEquals(BigInteger.valueOf(expectedDenominator), actual.getDenominator());
+ Assertions.assertEquals(expectedNumerator, actual.getNumeratorAsLong());
+ Assertions.assertEquals(expectedDenominator, actual.getDenominatorAsLong());
Assertions.assertEquals(
Long.signum(expectedNumerator) * Long.signum(expectedDenominator),
actual.signum());
@@ -472,15 +480,17 @@ public class BigFractionTest {
BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
+ BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add((long) i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(BigInteger.valueOf(i2)));
+ }
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigFraction) null));
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigInteger) null));
- BigFraction f1 = BigFraction.of(Integer.MAX_VALUE - 1, 1);
- assertFraction(Integer.MAX_VALUE, 1, f1.add(1));
- assertFraction(Integer.MAX_VALUE, 1, f1.add(1L));
- assertFraction(Integer.MAX_VALUE, 1, f1.add(BigInteger.ONE));
-
// Special cases
BigFraction f2 = BigFraction.of(1, 2);
assertFraction(1, 2, f2.add(BigInteger.ZERO));
@@ -494,6 +504,13 @@ public class BigFractionTest {
BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
+ BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide((long) i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(BigInteger.valueOf(i2)));
+ }
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigFraction) null));
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigInteger) null));
@@ -503,19 +520,8 @@ public class BigFractionTest {
Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(0L));
Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigInteger.ZERO));
- BigFraction f1 = BigFraction.of(0, 5);
- Assertions.assertEquals(BigFraction.ZERO, f1.divide(BigFraction.of(2, 7)));
- Assertions.assertEquals(BigFraction.ZERO, f1.divide(11));
- Assertions.assertEquals(BigFraction.ZERO, f1.divide(11L));
- Assertions.assertEquals(BigFraction.ZERO, f1.divide(BigInteger.valueOf(11)));
-
- f1 = BigFraction.of(6, 35);
- assertFraction(2, 175, f1.divide(15));
- assertFraction(2, 175, f1.divide(15L));
- assertFraction(2, 175, f1.divide(BigInteger.valueOf(15)));
-
// Special cases
- f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ BigFraction f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
assertFraction(-1, -Integer.MAX_VALUE, f1.divide(Integer.MIN_VALUE));
assertFraction(-1, -Integer.MAX_VALUE, f1.divide((long) Integer.MIN_VALUE));
assertFraction(-1, -Integer.MAX_VALUE, f1.divide(BigInteger.valueOf(Integer.MIN_VALUE)));
@@ -528,26 +534,16 @@ public class BigFractionTest {
BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
+ BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply((long) i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(BigInteger.valueOf(i2)));
+ }
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigFraction) null));
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigInteger) null));
-
- BigFraction f1 = BigFraction.of(6, 35);
- assertFraction(18, 7, f1.multiply(15));
- assertFraction(18, 7, f1.multiply((long) 15));
- assertFraction(18, 7, f1.multiply(BigInteger.valueOf(15)));
-
- f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- assertFraction(Integer.MIN_VALUE, 1, f1.multiply(Integer.MAX_VALUE));
- assertFraction(Integer.MIN_VALUE, 1, f1.multiply((long) Integer.MAX_VALUE));
- assertFraction(Integer.MIN_VALUE, 1, f1.multiply(BigInteger.valueOf(Integer.MAX_VALUE)));
-
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(42));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(42L));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(BigInteger.valueOf(42)));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(0));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(0L));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(BigInteger.ZERO));
}
@Test
@@ -573,18 +569,16 @@ public class BigFractionTest {
BigFraction f2 = BigFraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
+ BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract((long) i2));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(BigInteger.valueOf(i2)));
+ }
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigFraction) null));
Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigInteger) null));
-
- assertFraction(-3, 1, BigFraction.ZERO.subtract(3));
- assertFraction(-3, 1, BigFraction.ZERO.subtract(3L));
- assertFraction(-3, 1, BigFraction.ZERO.subtract(BigInteger.valueOf(3)));
-
- BigFraction f1 = BigFraction.of(2, 3);
- assertFraction(-7, 3, f1.subtract(3));
- assertFraction(-7, 3, f1.subtract(3L));
- assertFraction(-7, 3, f1.subtract(BigInteger.valueOf(3)));
}
@Test
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index 39ad560..fd4a37c 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -52,29 +52,47 @@ final class CommonTestCases {
*/
private static final List<UnaryOperatorTestCase> negateTestCasesList;
- // TODO addIntTestCasesList
-
/**
* See {@link #addFractionTestCases()}
*/
private static final List<BinaryOperatorTestCase> addFractionTestCasesList;
/**
+ * See {@link #addIntTestCases()}
+ */
+ private static final List<BinaryIntOperatorTestCase> addIntTestCasesList;
+
+ /**
* See {@link #divideByFractionTestCases()}
*/
private static final List<BinaryOperatorTestCase> divideByFractionTestCasesList;
/**
+ * See {@link #divideByIntTestCases()}
+ */
+ private static final List<BinaryIntOperatorTestCase> divideByIntTestCasesList;
+
+ /**
* See {@link #multiplyByFractionTestCases()}
*/
private static final List<BinaryOperatorTestCase> multiplyByFractionTestCasesList;
/**
+ * See {@link #multiplyByIntTestCases()}
+ */
+ private static final List<BinaryIntOperatorTestCase> multiplyByIntTestCasesList;
+
+ /**
* See {@link #subtractFractionTestCases()}
*/
private static final List<BinaryOperatorTestCase> subtractFractionTestCasesList;
/**
+ * See {@link #subtractIntTestCases()}
+ */
+ private static final List<BinaryIntOperatorTestCase> subtractIntTestCasesList;
+
+ /**
* See {@link #powTestCases()}
*/
private static final List<BinaryIntOperatorTestCase> powTestCasesList;
@@ -86,9 +104,13 @@ final class CommonTestCases {
reciprocalTestCasesList = collectReciprocalTestCases();
negateTestCasesList = collectNegateTestCases();
addFractionTestCasesList = collectAddFractionTestCases();
+ addIntTestCasesList = collectAddIntTestCases();
divideByFractionTestCasesList = collectDivideByFractionTestCases();
+ divideByIntTestCasesList = collectDivideByIntTestCases();
multiplyByFractionTestCasesList = collectMultiplyByFractionTestCases();
+ multiplyByIntTestCasesList = collectMultiplyByIntTestCases();
subtractFractionTestCasesList = collectSubtractFractionTestCases();
+ subtractIntTestCasesList = collectSubtractIntTestCases();
powTestCasesList = collectPowTestCases();
}
@@ -290,6 +312,23 @@ final class CommonTestCases {
}
/**
+ * Defines test cases as described in {@link #addIntTestCases()} and
+ * collects them into a {@code List}.
+ * @return a list of test cases as described above
+ */
+ private static List<BinaryIntOperatorTestCase> collectAddIntTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, 0, 1, 3));
+ testCases.add(new BinaryIntOperatorTestCase(-1, 3, 0, -1, 3));
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 4, 3));
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, -2, 3));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE - 1, 1, 1, Integer.MAX_VALUE, 1));
+
+ return testCases;
+ }
+
+ /**
* Defines test cases as described in
* {@link #divideByFractionTestCases()} and collects them into a {@code List}.
* @return a list of test cases as described above
@@ -323,6 +362,24 @@ final class CommonTestCases {
/**
* Defines test cases as described in
+ * {@link #divideByIntTestCases()} and collects them into a {@code List}.
+ * @return a list of test cases as described above
+ */
+ private static List<BinaryIntOperatorTestCase> collectDivideByIntTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
+ testCases.add(new BinaryIntOperatorTestCase(0, 5, 11, 0, 1));
+ testCases.add(new BinaryIntOperatorTestCase(6, 35, 15, 2, 175));
+
+ // This captures an implementation detail
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, 1, -3));
+
+ return testCases;
+ }
+
+ /**
+ * Defines test cases as described in
* {@link #multiplyByFractionTestCases()} and collects them into a {@code List}.
* @return a list of test cases as described above
*/
@@ -348,6 +405,27 @@ final class CommonTestCases {
/**
* Defines test cases as described in
+ * {@link #multiplyByIntTestCases()} and collects them into a {@code List}.
+ * @return a list of test cases as described above
+ */
+ private static List<BinaryIntOperatorTestCase> collectMultiplyByIntTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, 1, 3));
+ testCases.add(new BinaryIntOperatorTestCase(6, 35, 15, 18, 7));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, 1));
+ // Test zero with multiply by integer
+ testCases.add(new BinaryIntOperatorTestCase(0, 1, 42, 0, 1));
+ testCases.add(new BinaryIntOperatorTestCase(1, 1, 0, 0, 1));
+
+ // This captures an implementation detail
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, -1, -1, 3));
+
+ return testCases;
+ }
+
+ /**
+ * Defines test cases as described in
* {@link #subtractFractionTestCases()} and collects them into a {@code List}.
* @return a list of test cases as described above
*/
@@ -387,6 +465,22 @@ final class CommonTestCases {
/**
* Defines test cases as described in
+ * {@link #subtractIntTestCases()} and collects them into a {@code List}.
+ * @return a list of test cases as described above
+ */
+ private static List<BinaryIntOperatorTestCase> collectSubtractIntTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+
+ testCases.add(new BinaryIntOperatorTestCase(1, 3, 1, -2, 3));
+ testCases.add(new BinaryIntOperatorTestCase(0, 1, 3, -3, 1));
+ testCases.add(new BinaryIntOperatorTestCase(2, 3, 3, -7, 3));
+ testCases.add(new BinaryIntOperatorTestCase(2, 3, 0, 2, 3));
+
+ return testCases;
+ }
+
+ /**
+ * Defines test cases as described in
* {@link #powTestCases()} and collects them into a {@code List}.
* @return a list of test cases as described above
*/
@@ -479,6 +573,7 @@ final class CommonTestCases {
* specified numerator and denominator in the {@code int} range, should
* be added, and the expected numerator and denominator of the resulting
* fraction are also in the {@code int} range.
+ *
* @return a list of test cases as described above
*/
static List<BinaryOperatorTestCase> addFractionTestCases() {
@@ -488,6 +583,19 @@ final class CommonTestCases {
/**
* Provides a list of test cases where a fraction, created from a
* specified numerator and denominator in the {@code int} range, should
+ * be added to a specified value in the {@code int} range,
+ * and the expected numerator and denominator of the resulting fraction
+ * are in the {@code int} range as well.
+ *
+ * @return a list of test cases as described above
+ */
+ static List<BinaryIntOperatorTestCase> addIntTestCases() {
+ return Collections.unmodifiableList(addIntTestCasesList);
+ }
+
+ /**
+ * Provides a list of test cases where a fraction, created from a
+ * specified numerator and denominator in the {@code int} range, should
* be divided by another fraction, also created from a specified
* numerator and denominator in the {@code int} range, and the expected
* numerator and denominator of the resulting fraction are in the {@code
@@ -505,6 +613,22 @@ final class CommonTestCases {
/**
* Provides a list of test cases where a fraction, created from a
* specified numerator and denominator in the {@code int} range, should
+ * be divided by a specified value in the {@code int} range,
+ * and the expected numerator and denominator of the resulting fraction
+ * are in the {@code int} range as well.
+ *
+ * <p>The first operand in each test case is the dividend and the second
+ * operand is the divisor.</p>
+ *
+ * @return a list of test cases as described above
+ */
+ static List<BinaryIntOperatorTestCase> divideByIntTestCases() {
+ return Collections.unmodifiableList(divideByIntTestCasesList);
+ }
+
+ /**
+ * Provides a list of test cases where a fraction, created from a
+ * specified numerator and denominator in the {@code int} range, should
* be multiplied by another fraction, also created from a specified
* numerator and denominator in the {@code int} range, and the expected
* numerator and denominator of the resulting fraction are in the {@code
@@ -519,6 +643,19 @@ final class CommonTestCases {
/**
* Provides a list of test cases where a fraction, created from a
* specified numerator and denominator in the {@code int} range, should
+ * be multiplied by a specified value in the {@code int} range,
+ * and the expected numerator and denominator of the resulting fraction
+ * are in the {@code int} range as well.
+ *
+ * @return a list of test cases as described above
+ */
+ static List<BinaryIntOperatorTestCase> multiplyByIntTestCases() {
+ return Collections.unmodifiableList(multiplyByIntTestCasesList);
+ }
+
+ /**
+ * Provides a list of test cases where a fraction, created from a
+ * specified numerator and denominator in the {@code int} range, should
* be subtracted from another fraction, also created from a specified
* numerator and denominator in the {@code int} range, and the expected
* numerator and denominator of the resulting fraction are in the {@code
@@ -536,6 +673,22 @@ final class CommonTestCases {
/**
* Provides a list of test cases where a fraction, created from a
* specified numerator and denominator in the {@code int} range, should
+ * have a specified value in the {@code int} range subtracted,
+ * and the expected numerator and denominator of the resulting fraction
+ * are in the {@code int} range as well.
+ *
+ * <p>The first operand in each test case is the minuend and the second
+ * operand is the subtrahend.</p>
+ *
+ * @return a list of test cases as described above
+ */
+ static List<BinaryIntOperatorTestCase> subtractIntTestCases() {
+ return Collections.unmodifiableList(subtractIntTestCasesList);
+ }
+
+ /**
+ * Provides a list of test cases where a fraction, created from a
+ * specified numerator and denominator in the {@code int} range, should
* be raised to a specified power specified in the {@code int} range,
* and the expected numerator and denominator of the resulting fraction
* are in the {@code int} range as well.
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 6188d55..82fe803 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -303,12 +303,14 @@ public class FractionTest {
Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.addIntTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
- Fraction f1 = Fraction.of(Integer.MAX_VALUE - 1, 1);
- assertFraction(Integer.MAX_VALUE, 1, f1.add(1));
-
// Special cases
final Fraction f3 = Fraction.of(Integer.MAX_VALUE, 1);
Assertions.assertThrows(ArithmeticException.class,
@@ -350,19 +352,17 @@ public class FractionTest {
Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.divideByIntTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.divide((Fraction) null));
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(Fraction.ZERO));
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(0));
- Fraction f1 = Fraction.of(0, 5);
- Assertions.assertEquals(Fraction.ZERO, f1.divide(Fraction.of(2, 7)));
- Assertions.assertEquals(Fraction.ZERO, f1.divide(11));
-
- f1 = Fraction.of(6, 35);
- assertFraction(2, 175, f1.divide(15));
-
// Special cases
final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
Assertions.assertThrows(ArithmeticException.class,
@@ -382,18 +382,13 @@ public class FractionTest {
Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.multiplyByIntTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.multiply((Fraction) null));
-
- Fraction f1 = Fraction.of(6, 35);
- assertFraction(18, 7, f1.multiply(15));
-
- f1 = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- assertFraction(Integer.MIN_VALUE, 1, f1.multiply(Integer.MAX_VALUE));
-
- // Test zero with multiply by integer
- Assertions.assertEquals(Fraction.ZERO, Fraction.ZERO.multiply(42));
- Assertions.assertEquals(Fraction.ZERO, Fraction.ONE.multiply(0));
}
@Test
@@ -417,14 +412,14 @@ public class FractionTest {
Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.subtractIntTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
- assertFraction(-3, 1, Fraction.ZERO.subtract(3));
-
- Fraction f1 = Fraction.of(2, 3);
- assertFraction(-7, 3, f1.subtract(3));
-
final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
Assertions.assertThrows(ArithmeticException.class,
[commons-numbers] 04/26: Rename powFractionTestCases to powTestCases
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 7fa4f4be1d2b2ab36520dbe98ef950a3b267d264
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Apr 12 21:32:11 2020 +0100
Rename powFractionTestCases to powTestCases
---
.../commons/numbers/fraction/BigFractionTest.java | 20 ++++++++++----------
.../commons/numbers/fraction/CommonTestCases.java | 16 +++++++++-------
.../commons/numbers/fraction/FractionTest.java | 18 +++++++++---------
3 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index fe504d3..3a24a20 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -88,14 +88,6 @@ public class BigFractionTest {
() -> BigFraction.from(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000));
}
- @Test
- public void testGoldenRatio() {
- // the golden ratio is notoriously a difficult number for continuous fraction
- Assertions.assertThrows(FractionException.class,
- () -> BigFraction.from((1 + Math.sqrt(5)) / 2, 1.0e-12, 25)
- );
- }
-
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
@@ -142,11 +134,19 @@ public class BigFractionTest {
}
}
+ @Test
+ public void testDoubleConstructorGoldenRatioThrows() {
+ // the golden ratio is notoriously a difficult number for continuous fraction
+ Assertions.assertThrows(FractionException.class,
+ () -> BigFraction.from((1 + Math.sqrt(5)) / 2, 1.0e-12, 25)
+ );
+ }
+
// MATH-1029
@Test
public void testPositiveValueOverflow() {
Assertions.assertThrows(ArithmeticException.class,
- () -> assertFraction((long) 1e10, 1, BigFraction.from(1e10, 1000))
+ () -> BigFraction.from(1e10, 1000)
);
}
@@ -543,7 +543,7 @@ public class BigFractionTest {
@Test
public void testPow() {
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powFractionTestCases()) {
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
int exponent = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index efebc48..336add7 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -52,6 +52,8 @@ final class CommonTestCases {
*/
private static final List<UnaryOperatorTestCase> negateTestCasesList;
+ // TODO addIntTestCasesList
+
/**
* See {@link #addFractionTestCases()}
*/
@@ -73,9 +75,9 @@ final class CommonTestCases {
private static final List<BinaryOperatorTestCase> subtractFractionTestCasesList;
/**
- * See {@link #powFractionTestCases()}
+ * See {@link #powTestCases()}
*/
- private static final List<BinaryIntOperatorTestCase> powFractionTestCasesList;
+ private static final List<BinaryIntOperatorTestCase> powTestCasesList;
static {
numDenConstructorTestCasesList = collectNumDenConstructorTestCases();
@@ -87,7 +89,7 @@ final class CommonTestCases {
divideByFractionTestCasesList = collectDivideByFractionTestCases();
multiplyByFractionTestCasesList = collectMultiplyByFractionTestCases();
subtractFractionTestCasesList = collectSubtractFractionTestCases();
- powFractionTestCasesList = collectPowFractionTestCases();
+ powTestCasesList = collectPowTestCases();
}
private CommonTestCases() {}
@@ -382,10 +384,10 @@ final class CommonTestCases {
/**
* Defines test cases as described in
- * {@link #powFractionTestCases()} and collects them into a {@code List}.
+ * {@link #powTestCases()} and collects them into a {@code List}.
* @return a list of test cases as described above
*/
- private static List<BinaryIntOperatorTestCase> collectPowFractionTestCases() {
+ private static List<BinaryIntOperatorTestCase> collectPowTestCases() {
List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
testCases.add(new BinaryIntOperatorTestCase(3, 7, 0, 1, 1));
@@ -537,8 +539,8 @@ final class CommonTestCases {
*
* @return a list of test cases as described above
*/
- static List<BinaryIntOperatorTestCase> powFractionTestCases() {
- return Collections.unmodifiableList(powFractionTestCasesList);
+ static List<BinaryIntOperatorTestCase> powTestCases() {
+ return Collections.unmodifiableList(powTestCasesList);
}
// CHECKSTYLE: stop VisibilityModifier
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 584c28f..fccf015 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -65,14 +65,6 @@ public class FractionTest {
Assertions.assertThrows(ArithmeticException.class, () -> Fraction.of(1, 0));
}
- @Test
- public void testGoldenRatio() {
- // the golden ratio is notoriously a difficult number for continuous fraction
- Assertions.assertThrows(ArithmeticException.class,
- () -> Fraction.from((1 + Math.sqrt(5)) / 2, 1.0e-12, 25)
- );
- }
-
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
@@ -114,6 +106,14 @@ public class FractionTest {
}
@Test
+ public void testDoubleConstructorGoldenRatioThrows() {
+ // the golden ratio is notoriously a difficult number for continuous fraction
+ Assertions.assertThrows(ArithmeticException.class,
+ () -> Fraction.from((1 + Math.sqrt(5)) / 2, 1.0e-12, 25)
+ );
+ }
+
+ @Test
public void testIntegerOverflow() {
checkIntegerOverflow(0.75000000001455192);
checkIntegerOverflow(1.0e10);
@@ -396,7 +396,7 @@ public class FractionTest {
@Test
public void testPow() {
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powFractionTestCases()) {
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powTestCases()) {
Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
int exponent = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
[commons-numbers] 14/26: FractionTest: use assertFraction in
testMath1261
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit e55c35bffb5d73ba787e6da2c7af95cc4007beb3
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:02:07 2020 +0100
FractionTest: use assertFraction in testMath1261
---
.../commons/numbers/fraction/FractionTest.java | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index e62b577..f6b4842 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -271,17 +271,6 @@ public class FractionTest {
}
@Test
- public void testMath1261() {
- final Fraction a = Fraction.of(Integer.MAX_VALUE, 2);
- final Fraction b = a.multiply(2);
- Assertions.assertTrue(b.equals(Fraction.of(Integer.MAX_VALUE)));
-
- final Fraction c = Fraction.of(2, Integer.MAX_VALUE);
- final Fraction d = c.divide(2);
- Assertions.assertTrue(d.equals(Fraction.of(1, Integer.MAX_VALUE)));
- }
-
- @Test
public void testReciprocal() {
for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.reciprocalTestCases()) {
Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
@@ -619,4 +608,13 @@ public class FractionTest {
Assertions.assertThrows(NumberFormatException.class, () -> Fraction.parse("1 / --2"));
Assertions.assertThrows(NumberFormatException.class, () -> Fraction.parse("x"));
}
+
+ @Test
+ public void testMath1261() {
+ final Fraction a = Fraction.of(Integer.MAX_VALUE, 2);
+ assertFraction(Integer.MAX_VALUE, 1, a.multiply(2));
+
+ final Fraction b = Fraction.of(2, Integer.MAX_VALUE);
+ assertFraction(1, Integer.MAX_VALUE, b.divide(2));
+ }
}
[commons-numbers] 09/26: Fraction: Use canonical zero as 0 / 1
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit fa5b3eed90ac61ae4230ec0e69a9f10102d66d12
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Mon Apr 13 23:51:46 2020 +0100
Fraction: Use canonical zero as 0 / 1
Change arithmetic to return ZERO where applicable.
Change the factory constructor to return ZERO when the fraction is zero.
This removes the possibility to create 0 / -1. There should be no
equivalent of 0.0 and -0.0 in double. Thus compareTo, equals and
doubleValue() should function as if 0 / 1 and 0 / -1 are identical.
---
.../commons/numbers/fraction/BigFraction.java | 47 ++++++++++++++++---
.../apache/commons/numbers/fraction/Fraction.java | 53 +++++++++++++++-------
.../commons/numbers/fraction/BigFractionTest.java | 23 ++++++++--
.../commons/numbers/fraction/CommonTestCases.java | 11 ++---
.../commons/numbers/fraction/FractionTest.java | 22 +++++++--
5 files changed, 120 insertions(+), 36 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 1e60668..a62ced0 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -39,10 +39,10 @@ public final class BigFraction
NativeOperators<BigFraction>,
Serializable {
/** A fraction representing "0". */
- public static final BigFraction ZERO = of(0);
+ public static final BigFraction ZERO = new BigFraction(BigInteger.ZERO);
/** A fraction representing "1". */
- public static final BigFraction ONE = of(1);
+ public static final BigFraction ONE = new BigFraction(BigInteger.ONE);
/** Serializable version identifier. */
private static final long serialVersionUID = 20190701L;
@@ -59,6 +59,10 @@ public final class BigFraction
/**
* Private constructor: Instances are created using factory methods.
*
+ * <p>This constructor should only be invoked when the fraction is known
+ * to be non-zero; otherwise use {@link #ZERO}. This avoids creating
+ * the zero representation {@code 0 / -1}.
+ *
* @param num Numerator, must not be {@code null}.
* @param den Denominator, must not be {@code null}.
* @throws ArithmeticException if the denominator is zero.
@@ -134,6 +138,9 @@ public final class BigFraction
if (!Double.isFinite(value)) {
throw new IllegalArgumentException(NOT_FINITE + value);
}
+ if (value == 0) {
+ return ZERO;
+ }
final long overflow = Integer.MAX_VALUE;
double r0 = value;
@@ -231,6 +238,9 @@ public final class BigFraction
if (!Double.isFinite(value)) {
throw new IllegalArgumentException(NOT_FINITE + value);
}
+ if (value == 0) {
+ return ZERO;
+ }
final long bits = Double.doubleToLongBits(value);
final long sign = bits & 0x8000000000000000L;
@@ -320,6 +330,9 @@ public final class BigFraction
* @return a new instance.
*/
public static BigFraction of(final int num) {
+ if (num == 0) {
+ return ZERO;
+ }
return new BigFraction(BigInteger.valueOf(num));
}
@@ -330,6 +343,9 @@ public final class BigFraction
* @return a new instance.
*/
public static BigFraction of(final long num) {
+ if (num == 0) {
+ return ZERO;
+ }
return new BigFraction(BigInteger.valueOf(num));
}
@@ -342,6 +358,9 @@ public final class BigFraction
*/
public static BigFraction of(final BigInteger num) {
Objects.requireNonNull(num, "numerator");
+ if (num.signum() == 0) {
+ return ZERO;
+ }
return new BigFraction(num);
}
@@ -355,6 +374,9 @@ public final class BigFraction
* @throws ArithmeticException if {@code den} is zero.
*/
public static BigFraction of(final int num, final int den) {
+ if (num == 0) {
+ return ZERO;
+ }
return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
}
@@ -368,6 +390,9 @@ public final class BigFraction
* @throws ArithmeticException if {@code den} is zero.
*/
public static BigFraction of(final long num, final long den) {
+ if (num == 0) {
+ return ZERO;
+ }
return new BigFraction(BigInteger.valueOf(num), BigInteger.valueOf(den));
}
@@ -382,6 +407,9 @@ public final class BigFraction
* @throws ArithmeticException if the denominator is zero.
*/
public static BigFraction of(final BigInteger num, final BigInteger den) {
+ if (num.signum() == 0) {
+ return ZERO;
+ }
return new BigFraction(num, den);
}
@@ -423,7 +451,7 @@ public final class BigFraction
final int slashLoc = stripped.indexOf('/');
// if no slash, parse as single number
if (slashLoc == -1) {
- return BigFraction.of(new BigInteger(stripped.trim()));
+ return of(new BigInteger(stripped.trim()));
}
final BigInteger num = new BigInteger(stripped.substring(0, slashLoc).trim());
final BigInteger denom = new BigInteger(stripped.substring(slashLoc + 1).trim());
@@ -654,6 +682,7 @@ public final class BigFraction
return of(value);
}
+ // Direct constructor: cannot add an integer to a fraction to produce zero
return new BigFraction(numerator.add(denominator.multiply(value)), denominator);
}
@@ -728,6 +757,7 @@ public final class BigFraction
return of(value.negate());
}
+ // Direct constructor: cannot subtract an integer from a fraction to produce zero
return new BigFraction(numerator.subtract(denominator.multiply(value)), denominator);
}
@@ -756,6 +786,11 @@ public final class BigFraction
num = (numerator.multiply(value.denominator)).subtract((value.numerator).multiply(denominator));
den = denominator.multiply(value.denominator);
}
+
+ if (num.signum() == 0) {
+ return ZERO;
+ }
+
return new BigFraction(num, den);
}
@@ -857,7 +892,7 @@ public final class BigFraction
throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
}
if (isZero()) {
- return this;
+ return ZERO;
}
return new BigFraction(numerator, denominator.multiply(value));
}
@@ -876,7 +911,7 @@ public final class BigFraction
throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
}
if (isZero()) {
- return this;
+ return ZERO;
}
return multiply(value.reciprocal());
}
@@ -895,7 +930,7 @@ public final class BigFraction
return ONE;
}
if (isZero()) {
- return this;
+ return ZERO;
}
// Note: Raise the BigIntegers to the power and then reduce.
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 5154eff..a9401db 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -36,10 +36,10 @@ public final class Fraction
NativeOperators<Fraction>,
Serializable {
/** A fraction representing "0". */
- public static final Fraction ZERO = of(0);
+ public static final Fraction ZERO = new Fraction(0);
/** A fraction representing "1". */
- public static final Fraction ONE = of(1);
+ public static final Fraction ONE = new Fraction(1);
/** Serializable version identifier. */
private static final long serialVersionUID = 20190701L;
@@ -59,6 +59,10 @@ public final class Fraction
/**
* Private constructor: Instances are created using factory methods.
*
+ * <p>This constructor should only be invoked when the fraction is known
+ * to be non-zero; otherwise use {@link #ZERO}. This avoids creating
+ * the zero representation {@code 0 / -1}.
+ *
* @param num Numerator.
* @param den Denominator.
* @throws ArithmeticException if the denominator is {@code zero}.
@@ -87,15 +91,11 @@ public final class Fraction
q = den;
}
- // Will not throw
+ // Will not throw.
+ // Cannot return 0 as gcd(0, 0) has been eliminated.
final int d = ArithmeticUtils.gcd(p, q);
- if (d > 1) {
- p /= d;
- q /= d;
- }
-
- numerator = p;
- denominator = q;
+ numerator = p / d;
+ denominator = q / d;
}
}
@@ -257,6 +257,9 @@ public final class Fraction
public static Fraction from(final double value,
final double epsilon,
final int maxIterations) {
+ if (value == 0) {
+ return ZERO;
+ }
return new Fraction(value, epsilon, Integer.MAX_VALUE, maxIterations);
}
@@ -278,6 +281,9 @@ public final class Fraction
*/
public static Fraction from(final double value,
final int maxDenominator) {
+ if (value == 0) {
+ return ZERO;
+ }
return new Fraction(value, 0, maxDenominator, 100);
}
@@ -288,6 +294,9 @@ public final class Fraction
* @return a new instance.
*/
public static Fraction of(final int num) {
+ if (num == 0) {
+ return ZERO;
+ }
return new Fraction(num);
}
@@ -301,6 +310,9 @@ public final class Fraction
* @return a new instance.
*/
public static Fraction of(final int num, final int den) {
+ if (num == 0) {
+ return ZERO;
+ }
return new Fraction(num, den);
}
@@ -342,7 +354,7 @@ public final class Fraction
final int slashLoc = stripped.indexOf('/');
// if no slash, parse as single number
if (slashLoc == -1) {
- return Fraction.of(Integer.parseInt(stripped.trim()));
+ return of(Integer.parseInt(stripped.trim()));
}
final int num = Integer.parseInt(stripped.substring(0, slashLoc).trim());
final int denom = Integer.parseInt(stripped.substring(slashLoc + 1).trim());
@@ -469,6 +481,7 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction add(final int value) {
+ // Direct constructor: cannot add an integer to a fraction to produce zero
return new Fraction(numerator + value * denominator, denominator);
}
@@ -496,6 +509,7 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction subtract(final int value) {
+ // Direct constructor: cannot subtract an integer from a fraction to produce zero
return new Fraction(numerator - value * denominator, denominator);
}
@@ -600,8 +614,8 @@ public final class Fraction
// Make sure we don't overflow unless the result *must* overflow.
final int d1 = ArithmeticUtils.gcd(numerator, value.denominator);
final int d2 = ArithmeticUtils.gcd(value.numerator, denominator);
- return of(Math.multiplyExact(numerator / d1, value.numerator / d2),
- Math.multiplyExact(denominator / d2, value.denominator / d1));
+ return new Fraction(Math.multiplyExact(numerator / d1, value.numerator / d2),
+ Math.multiplyExact(denominator / d2, value.denominator / d1));
}
/**
@@ -615,7 +629,14 @@ public final class Fraction
* by an {@code int}.
*/
public Fraction divide(final int value) {
- return divide(of(value));
+ if (value == 0) {
+ throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
+ }
+ if (isZero()) {
+ return ZERO;
+ }
+ // Multiply by reciprocal
+ return multiply(new Fraction(1, value));
}
/**
@@ -634,7 +655,7 @@ public final class Fraction
throw new FractionException(FractionException.ERROR_DIVIDE_BY_ZERO);
}
if (isZero()) {
- return this;
+ return ZERO;
}
return multiply(value.reciprocal());
}
@@ -653,7 +674,7 @@ public final class Fraction
return ONE;
}
if (isZero()) {
- return this;
+ return ZERO;
}
if (exponent < 0) {
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index bdc8003..8e4d90b 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -96,6 +96,22 @@ public class BigFractionTest {
() -> BigFraction.from(2.0 * Integer.MAX_VALUE, 1.0e-5, 100000));
}
+ @Test
+ public void testConstructorZero() {
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0, 1e-10, 100));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.from(0.0, 100));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0, 1));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0, -1));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L, 1L));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(0L, -1L));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO, BigInteger.ONE));
+ Assertions.assertSame(BigFraction.ZERO, BigFraction.of(BigInteger.ZERO, BigInteger.ONE.negate()));
+ }
+
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
@@ -624,14 +640,15 @@ public class BigFractionTest {
* Assert the two fractions are equal. The contract of {@link Object#hashCode()} requires
* that the hash code must also be equal.
*
- * <p>This method must not be called with the same instance for both arguments. It is
- * intended to be used to test different objects that are equal have the same hash code.
+ * <p>Ideally this method should not be called with the same instance for both arguments.
+ * It is intended to be used to test different objects that are equal have the same hash code.
+ * However the same object may be constructed for different arguments using factory
+ * constructors, e.g. zero.
*
* @param f1 Fraction 1.
* @param f2 Fraction 2.
*/
private static void assertEqualAndHashCodeEqual(BigFraction f1, BigFraction f2) {
- Assertions.assertNotSame(f1, f2, "Do not call this assertion with the same object");
Assertions.assertEquals(f1, f2);
Assertions.assertEquals(f1.hashCode(), f2.hashCode(), "Equal fractions have different hashCode");
// Check the computation matches the result of Arrays.hashCode and the signum.
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
index fd4a37c..5f7c9e7 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/CommonTestCases.java
@@ -127,7 +127,7 @@ final class CommonTestCases {
testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
testCases.add(new UnaryOperatorTestCase(0, 2, 0, 1));
- testCases.add(new UnaryOperatorTestCase(0, -1, 0, -1));
+ testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
testCases.add(new UnaryOperatorTestCase(1, 2, 1, 2));
testCases.add(new UnaryOperatorTestCase(2, 4, 1, 2));
testCases.add(new UnaryOperatorTestCase(-1, 2, -1, 2));
@@ -216,7 +216,7 @@ final class CommonTestCases {
testCases.add(new UnaryOperatorTestCase(-11, 23, 11, 23));
testCases.add(new UnaryOperatorTestCase(13, -24, -13, -24));
testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
- testCases.add(new UnaryOperatorTestCase(0, -1, 0, -1));
+ testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
return testCases;
}
@@ -249,9 +249,8 @@ final class CommonTestCases {
testCases.add(new UnaryOperatorTestCase(-50, 75, 2, 3));
testCases.add(new UnaryOperatorTestCase(Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Integer.MIN_VALUE + 2, Integer.MAX_VALUE));
testCases.add(new UnaryOperatorTestCase(1, Integer.MIN_VALUE, -1, Integer.MIN_VALUE));
- // Negation of zero is a no-op
testCases.add(new UnaryOperatorTestCase(0, 1, 0, 1));
- testCases.add(new UnaryOperatorTestCase(0, -1, 0, -1));
+ testCases.add(new UnaryOperatorTestCase(0, -1, 0, 1));
// XXX Failed by "BigFraction" (whose implementation differs from "Fraction").
// These are tested explicitly in FractionTest.
@@ -342,7 +341,7 @@ final class CommonTestCases {
testCases.add(new BinaryOperatorTestCase(2, 3, 2, 3, 1, 1));
testCases.add(new BinaryOperatorTestCase(0, 3, 2, 3, 0, 1));
// Return the original zero representation
- testCases.add(new BinaryOperatorTestCase(0, -3, 2, 3, 0, -1));
+ testCases.add(new BinaryOperatorTestCase(0, -3, 2, 3, 0, 1));
testCases.add(new BinaryOperatorTestCase(
2, 7,
@@ -503,7 +502,7 @@ final class CommonTestCases {
testCases.add(new BinaryIntOperatorTestCase(2, 3, -13, 1594323, 8192));
testCases.add(new BinaryIntOperatorTestCase(0, 1, Integer.MAX_VALUE, 0, 1));
- testCases.add(new BinaryIntOperatorTestCase(0, -1, Integer.MAX_VALUE, 0, -1));
+ testCases.add(new BinaryIntOperatorTestCase(0, -1, Integer.MAX_VALUE, 0, 1));
return testCases;
}
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 7205c6b..e62b577 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.numbers.fraction;
+import java.math.BigInteger;
import java.util.Arrays;
import org.apache.commons.numbers.core.TestUtils;
@@ -65,6 +66,16 @@ public class FractionTest {
Assertions.assertThrows(ArithmeticException.class, () -> Fraction.of(1, 0));
}
+ @Test
+ public void testConstructorZero() {
+ Assertions.assertSame(Fraction.ZERO, Fraction.from(0.0));
+ Assertions.assertSame(Fraction.ZERO, Fraction.from(0.0, 1e-10, 100));
+ Assertions.assertSame(Fraction.ZERO, Fraction.from(0.0, 100));
+ Assertions.assertSame(Fraction.ZERO, Fraction.of(0));
+ Assertions.assertSame(Fraction.ZERO, Fraction.of(0, 1));
+ Assertions.assertSame(Fraction.ZERO, Fraction.of(0, -1));
+ }
+
// MATH-179
@Test
public void testDoubleConstructor() throws Exception {
@@ -199,7 +210,7 @@ public class FractionTest {
Assertions.assertEquals(0.0, Fraction.ZERO.doubleValue());
Assertions.assertEquals(0.0, ZERO_P.doubleValue());
- Assertions.assertEquals(-0.0, ZERO_N.doubleValue());
+ Assertions.assertEquals(0.0, ZERO_N.doubleValue());
}
@Test
@@ -216,7 +227,7 @@ public class FractionTest {
Assertions.assertEquals(-e, Fraction.of(1, -3).floatValue());
Assertions.assertEquals(0.0f, ZERO_P.floatValue());
- Assertions.assertEquals(-0.0f, ZERO_N.floatValue());
+ Assertions.assertEquals(0.0f, ZERO_N.floatValue());
}
@Test
@@ -510,14 +521,15 @@ public class FractionTest {
* Assert the two fractions are equal. The contract of {@link Object#hashCode()} requires
* that the hash code must also be equal.
*
- * <p>This method must not be called with the same instance for both arguments. It is
- * intended to be used to test different objects that are equal have the same hash code.
+ * <p>Ideally this method should not be called with the same instance for both arguments.
+ * It is intended to be used to test different objects that are equal have the same hash code.
+ * However the same object may be constructed for different arguments using factory
+ * constructors, e.g. zero.
*
* @param f1 Fraction 1.
* @param f2 Fraction 2.
*/
private static void assertEqualAndHashCodeEqual(Fraction f1, Fraction f2) {
- Assertions.assertNotSame(f1, f2, "Do not call this assertion with the same object");
Assertions.assertEquals(f1, f2);
Assertions.assertEquals(f1.hashCode(), f2.hashCode(), "Equal fractions have different hashCode");
// Check the computation matches the result of Arrays.hashCode and the signum.
[commons-numbers] 19/26: FractionTest: overflow check in
multiply/divide by int
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 83098b7bec08e11829dc419a556b34a142809776
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:59:37 2020 +0100
FractionTest: overflow check in multiply/divide by int
---
.../commons/numbers/fraction/FractionTest.java | 33 ++++++++++++++++------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 96b0a25..7042e82 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -351,16 +351,19 @@ public class FractionTest {
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(Fraction.ZERO));
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(0));
- // Special cases
+ // Special cases for overflow
+ final Fraction two = Fraction.of(2);
final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f3.divide(f3.reciprocal()) // should overflow
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(two));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(two.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(2));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(-2));
- final Fraction f4 = Fraction.of(1, -Integer.MAX_VALUE);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f4.divide(f4.reciprocal()) // should overflow
- );
+ final Fraction f4 = Fraction.of(1, Integer.MIN_VALUE);
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(two));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(two.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(2));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(-2));
}
@Test
@@ -377,6 +380,20 @@ public class FractionTest {
}
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.multiply((Fraction) null));
+
+ // Special cases for overflow
+ final Fraction two = Fraction.of(2);
+ final Fraction f3 = Fraction.of(Integer.MAX_VALUE);
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(two));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(two.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(2));
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(-2));
+
+ final Fraction f4 = Fraction.of(Integer.MIN_VALUE);
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(two));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(two.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(2));
+ Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(-2));
}
@Test
[commons-numbers] 10/26: Fraction: update toString()
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 4356bd947a81343e093254116d0798870e959521
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 00:08:34 2020 +0100
Fraction: update toString()
Since zero is a canonical value (0 / 1) it cannot be obtained in
toString when the denominator is not 1. Rearrange the toString logic to
test for zero first.
---
.../main/java/org/apache/commons/numbers/fraction/BigFraction.java | 6 +++---
.../src/main/java/org/apache/commons/numbers/fraction/Fraction.java | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index a62ced0..6a16541 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -959,10 +959,10 @@ public final class BigFraction
@Override
public String toString() {
final String str;
- if (BigInteger.ONE.equals(denominator)) {
- str = numerator.toString();
- } else if (isZero()) {
+ if (isZero()) {
str = "0";
+ } else if (BigInteger.ONE.equals(denominator)) {
+ str = numerator.toString();
} else {
str = numerator + " / " + denominator;
}
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index a9401db..be42d68 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -699,10 +699,10 @@ public final class Fraction
@Override
public String toString() {
final String str;
- if (denominator == 1) {
- str = Integer.toString(numerator);
- } else if (isZero()) {
+ if (isZero()) {
str = "0";
+ } else if (denominator == 1) {
+ str = Integer.toString(numerator);
} else {
str = numerator + " / " + denominator;
}
[commons-numbers] 01/26: Fraction: Add tests for two
representations of zero.
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 828f6a728d92e1ae911233ea2da9c100586f8d2d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Apr 12 12:30:55 2020 +0100
Fraction: Add tests for two representations of zero.
BigFraction handles the conversion to double and float differently than
Fraction as it does not support negative zero.
---
.../commons/numbers/fraction/BigFractionTest.java | 19 +++++++++++++++++++
.../apache/commons/numbers/fraction/FractionTest.java | 19 +++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 40dc9e9..6afa2cf 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -27,6 +27,11 @@ import org.junit.jupiter.api.Test;
public class BigFractionTest {
+ /** The zero representation with positive denominator. */
+ private static final BigFraction ZERO_P = BigFraction.of(0, 1);
+ /** The zero representation with negative denominator. */
+ private static final BigFraction ZERO_N = BigFraction.of(0, -1);
+
private static void assertFraction(long expectedNumerator, long expectedDenominator, BigFraction actual) {
Assertions.assertEquals(BigInteger.valueOf(expectedNumerator), actual.getNumerator());
Assertions.assertEquals(BigInteger.valueOf(expectedDenominator), actual.getDenominator());
@@ -186,6 +191,8 @@ public class BigFractionTest {
Assertions.assertEquals(-1, pi1.compareTo(pi2));
Assertions.assertEquals(1, pi2.compareTo(pi1));
Assertions.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
+
+ Assertions.assertEquals(0, ZERO_P.compareTo(ZERO_N));
}
@Test
@@ -198,6 +205,9 @@ public class BigFractionTest {
assertDoubleValue(0.5, -1, -2);
assertDoubleValue(1.0 / 3.0, 1, 3);
+ Assertions.assertEquals(0.0, ZERO_P.doubleValue());
+ Assertions.assertEquals(0.0, ZERO_N.doubleValue());
+
//NUMBERS-120
assertDoubleValue(
2d - 0x1P-52,
@@ -357,6 +367,9 @@ public class BigFractionTest {
Assertions.assertEquals(e, BigFraction.of(-1, -3).floatValue(), 0.0f);
Assertions.assertEquals(-e, BigFraction.of(-1, 3).floatValue(), 0.0f);
Assertions.assertEquals(-e, BigFraction.of(1, -3).floatValue(), 0.0f);
+
+ Assertions.assertEquals(0.0f, ZERO_P.floatValue());
+ Assertions.assertEquals(0.0f, ZERO_N.floatValue());
}
@Test
@@ -370,6 +383,9 @@ public class BigFractionTest {
Assertions.assertEquals(1, BigFraction.of(-3, -2).intValue());
Assertions.assertEquals(-1, BigFraction.of(-3, 2).intValue());
Assertions.assertEquals(-1, BigFraction.of(3, -2).intValue());
+
+ Assertions.assertEquals(0, ZERO_P.intValue());
+ Assertions.assertEquals(0, ZERO_N.intValue());
}
@Test
@@ -383,6 +399,9 @@ public class BigFractionTest {
Assertions.assertEquals(1L, BigFraction.of(-3, -2).longValue());
Assertions.assertEquals(-1L, BigFraction.of(-3, 2).longValue());
Assertions.assertEquals(-1L, BigFraction.of(3, -2).longValue());
+
+ Assertions.assertEquals(0, ZERO_P.longValue());
+ Assertions.assertEquals(0, ZERO_N.longValue());
}
@Test
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 5644c72..9f663e3 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -26,6 +26,11 @@ import org.junit.jupiter.api.Test;
*/
public class FractionTest {
+ /** The zero representation with positive denominator. */
+ private static final Fraction ZERO_P = Fraction.of(0, 1);
+ /** The zero representation with negative denominator. */
+ private static final Fraction ZERO_N = Fraction.of(0, -1);
+
private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
Assertions.assertEquals(expectedNumerator, actual.getNumerator());
Assertions.assertEquals(expectedDenominator, actual.getDenominator());
@@ -147,6 +152,8 @@ public class FractionTest {
Assertions.assertEquals(-1, pi1.compareTo(pi2));
Assertions.assertEquals(1, pi2.compareTo(pi1));
Assertions.assertEquals(0.0, pi1.doubleValue() - pi2.doubleValue(), 1.0e-20);
+
+ Assertions.assertEquals(0, ZERO_P.compareTo(ZERO_N));
}
@Test
@@ -156,6 +163,9 @@ public class FractionTest {
Assertions.assertEquals(0.5, first.doubleValue(), 0.0);
Assertions.assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
+
+ Assertions.assertEquals(0.0, ZERO_P.doubleValue());
+ Assertions.assertEquals(-0.0, ZERO_N.doubleValue());
}
@Test
@@ -165,6 +175,9 @@ public class FractionTest {
Assertions.assertEquals(0.5f, first.floatValue(), 0.0f);
Assertions.assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
+
+ Assertions.assertEquals(0.0f, ZERO_P.floatValue());
+ Assertions.assertEquals(-0.0f, ZERO_N.floatValue());
}
@Test
@@ -174,6 +187,9 @@ public class FractionTest {
Assertions.assertEquals(0, first.intValue());
Assertions.assertEquals(1, second.intValue());
+
+ Assertions.assertEquals(0, ZERO_P.intValue());
+ Assertions.assertEquals(0, ZERO_N.intValue());
}
@Test
@@ -183,6 +199,9 @@ public class FractionTest {
Assertions.assertEquals(0L, first.longValue());
Assertions.assertEquals(1L, second.longValue());
+
+ Assertions.assertEquals(0L, ZERO_P.longValue());
+ Assertions.assertEquals(0L, ZERO_N.longValue());
}
@Test
[commons-numbers] 12/26: Fraction: efficient divide by integer
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 368187dd96e44430ed3eff270dfec171298a7149
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 00:21:47 2020 +0100
Fraction: efficient divide by integer
---
.../main/java/org/apache/commons/numbers/fraction/Fraction.java | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 5eb3beb..d424045 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -595,6 +595,7 @@ public final class Fraction
// knuth 4.5.1
// Make sure we don't overflow unless the result *must* overflow.
+ // (see multiply(Fraction) using value / 1 as the argument).
final int d2 = ArithmeticUtils.gcd(value, denominator);
return new Fraction(Math.multiplyExact(numerator, value / d2),
denominator / d2);
@@ -641,7 +642,13 @@ public final class Fraction
return ZERO;
}
// Multiply by reciprocal
- return multiply(new Fraction(1, value));
+
+ // knuth 4.5.1
+ // Make sure we don't overflow unless the result *must* overflow.
+ // (see multiply(Fraction) using 1 / value as the argument).
+ final int d1 = ArithmeticUtils.gcd(numerator, value);
+ return new Fraction(numerator / d1,
+ Math.multiplyExact(denominator, value / d1));
}
/**
[commons-numbers] 18/26: Fraction: fix overflow detection in
add/subtract int
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit e3f69b746cc89f4c8ef8efb390c854131cc19842
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:53:25 2020 +0100
Fraction: fix overflow detection in add/subtract int
---
.../apache/commons/numbers/fraction/Fraction.java | 12 ++--
.../commons/numbers/fraction/FractionTest.java | 72 ++++++++--------------
2 files changed, 32 insertions(+), 52 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index ce6954b..7d025d9 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -477,11 +477,13 @@ public final class Fraction
*
* @param value Value to add.
* @return {@code this + value}.
- * @throws ArithmeticException if the resulting numerator or denominator
+ * @throws ArithmeticException if the resulting numerator
* cannot be represented in an {@code int}.
*/
public Fraction add(final int value) {
- return of(numerator + value * denominator, denominator);
+ // Convert to numerator with same effective denominator
+ final long f = (long) value * denominator;
+ return of(Math.toIntExact(numerator + f), denominator);
}
/**
@@ -504,11 +506,13 @@ public final class Fraction
*
* @param value Value to subtract.
* @return {@code this - value}.
- * @throws ArithmeticException if the resulting numerator or denominator
+ * @throws ArithmeticException if the resulting numerator
* cannot be represented in an {@code int}.
*/
public Fraction subtract(final int value) {
- return of(numerator - value * denominator, denominator);
+ // Convert to numerator with same effective denominator
+ final long f = (long) value * denominator;
+ return of(Math.toIntExact(numerator - f), denominator);
}
/**
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 18803d1..96b0a25 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -311,37 +311,26 @@ public class FractionTest {
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
// Special cases
- final Fraction f3 = Fraction.of(Integer.MAX_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class,
- () -> {
- Fraction f = f3.add(Fraction.ONE); // should overflow
- Assertions.fail("expecting ArithmeticException but got: " + f.toString());
- }
- );
+ final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
+ final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.add(f4));
// denominator should not be a multiple of 2 or 3 to trigger overflow
- final Fraction f4 = Fraction.of(Integer.MIN_VALUE, 5);
- final Fraction f5 = Fraction.of(-1, 5);
- Assertions.assertThrows(ArithmeticException.class,
- () -> {
- Fraction f = f4.add(f5); // should overflow
- Assertions.fail("expecting ArithmeticException but got: " + f.toString());
- }
- );
+ final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 5);
+ final Fraction f6 = Fraction.of(-1, 5);
+ Assertions.assertThrows(ArithmeticException.class, () -> f5.add(f6));
- final Fraction f6 = Fraction.of(-Integer.MAX_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f6.add(f6)
- );
+ final Fraction f7 = Fraction.of(Integer.MIN_VALUE, 1);
+ Assertions.assertThrows(ArithmeticException.class, () -> f7.add(Fraction.ONE.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f7.add(-1));
- final Fraction f7 = Fraction.of(3, 327680);
- final Fraction f8 = Fraction.of(2, 59049);
- Assertions.assertThrows(ArithmeticException.class,
- () -> {
- Fraction f = f7.add(f8); // should overflow
- Assertions.fail("expecting ArithmeticException but got: " + f.toString());
- }
- );
+ final Fraction f8 = Fraction.of(Integer.MAX_VALUE, 1);
+ Assertions.assertThrows(ArithmeticException.class, () -> f8.add(Fraction.ONE));
+ Assertions.assertThrows(ArithmeticException.class, () -> f8.add(1));
+
+ final Fraction f9 = Fraction.of(3, 327680);
+ final Fraction f10 = Fraction.of(2, 59049);
+ Assertions.assertThrows(ArithmeticException.class, () -> f9.add(f10));
}
@Test
@@ -419,40 +408,27 @@ public class FractionTest {
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
+ // Special cases
final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f3.subtract(f4) //should overflow
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f3.subtract(f4));
// denominator should not be a multiple of 2 or 3 to trigger overflow
final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 5);
final Fraction f6 = Fraction.of(1, 5);
- Assertions.assertThrows(ArithmeticException.class,
- () -> {
- Fraction f = f5.subtract(f6); // should overflow
- Assertions.fail("expecting ArithmeticException but got: " + f.toString());
- }
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f5.subtract(f6));
final Fraction f7 = Fraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f7.subtract(Fraction.ONE)
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f7.subtract(Fraction.ONE));
+ Assertions.assertThrows(ArithmeticException.class, () -> f7.subtract(1));
final Fraction f8 = Fraction.of(Integer.MAX_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class,
- () -> f8.subtract(Fraction.ONE.negate())
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f8.subtract(Fraction.ONE.negate()));
+ Assertions.assertThrows(ArithmeticException.class, () -> f8.subtract(-1));
final Fraction f9 = Fraction.of(3, 327680);
final Fraction f10 = Fraction.of(2, 59049);
- Assertions.assertThrows(ArithmeticException.class,
- () -> {
- Fraction f = f9.subtract(f10); // should overflow
- Assertions.fail("expecting ArithmeticException but got: " + f.toString());
- }
- );
+ Assertions.assertThrows(ArithmeticException.class, () -> f9.subtract(f10));
}
@Test
[commons-numbers] 02/26: Use consistent order and tests in
FractionTest and BigFractionTest.
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 7ad0f911ad41b69b52fffdf07d2cda11897aec6d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sun Apr 12 14:01:39 2020 +0100
Use consistent order and tests in FractionTest and BigFractionTest.
Copy missing tests from each class to the other when applicable.
The compare function in Fraction currently fails and assertions are
commented out.
---
.../commons/numbers/fraction/BigFractionTest.java | 290 ++++++++++-----------
.../commons/numbers/fraction/FractionTest.java | 228 ++++++++--------
2 files changed, 261 insertions(+), 257 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 6afa2cf..fe504d3 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -25,6 +25,9 @@ import org.apache.commons.numbers.core.TestUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+/**
+ * Tests for {@link BigFraction}.
+ */
public class BigFractionTest {
/** The zero representation with positive denominator. */
@@ -43,6 +46,9 @@ public class BigFractionTest {
private static void assertFraction(BigInteger expectedNumerator, BigInteger expectedDenominator, BigFraction actual) {
Assertions.assertEquals(expectedNumerator, actual.getNumerator());
Assertions.assertEquals(expectedDenominator, actual.getDenominator());
+ Assertions.assertEquals(
+ expectedNumerator.signum() * expectedDenominator.signum(),
+ actual.signum());
}
private static void assertDoubleValue(double expected, BigInteger numerator, BigInteger denominator) {
@@ -64,17 +70,12 @@ public class BigFractionTest {
);
}
+ // Long/BigInteger arguments
assertFraction(0, 1, BigFraction.of(0L, 2L));
assertFraction(1L, 1, BigFraction.of(1L));
assertFraction(11, 1, BigFraction.of(11L));
assertFraction(11, 1, BigFraction.of(new BigInteger("11")));
- Assertions.assertEquals(0.00000000000001, BigFraction.from(0.00000000000001).doubleValue(), 0.0);
- Assertions.assertEquals(0.40000000000001, BigFraction.from(0.40000000000001).doubleValue(), 0.0);
- Assertions.assertEquals(15.0000000000001, BigFraction.from(15.0000000000001).doubleValue(), 0.0);
- assertFraction(3602879701896487L, 9007199254740992L, BigFraction.from(0.40000000000001));
- assertFraction(1055531162664967L, 70368744177664L, BigFraction.from(15.0000000000001));
-
// Divide by zero
Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(BigInteger.ONE, BigInteger.ZERO));
@@ -105,18 +106,24 @@ public class BigFractionTest {
BigFraction.from(testCase.operand, 1.0e-5, 100)
);
}
+
+ Assertions.assertEquals(0.00000000000001, BigFraction.from(0.00000000000001).doubleValue());
+ Assertions.assertEquals(0.40000000000001, BigFraction.from(0.40000000000001).doubleValue());
+ Assertions.assertEquals(15.0000000000001, BigFraction.from(15.0000000000001).doubleValue());
+ assertFraction(3602879701896487L, 9007199254740992L, BigFraction.from(0.40000000000001));
+ assertFraction(1055531162664967L, 70368744177664L, BigFraction.from(15.0000000000001));
}
// MATH-181
@Test
public void testDigitLimitConstructor() throws Exception {
- assertFraction(2, 5, BigFraction.from(0.4, 9));
- assertFraction(2, 5, BigFraction.from(0.4, 99));
+ assertFraction(2, 5, BigFraction.from(0.4, 9));
+ assertFraction(2, 5, BigFraction.from(0.4, 99));
assertFraction(2, 5, BigFraction.from(0.4, 999));
- assertFraction(3, 5, BigFraction.from(0.6152, 9));
- assertFraction(8, 13, BigFraction.from(0.6152, 99));
- assertFraction(510, 829, BigFraction.from(0.6152, 999));
+ assertFraction(3, 5, BigFraction.from(0.6152, 9));
+ assertFraction(8, 13, BigFraction.from(0.6152, 99));
+ assertFraction(510, 829, BigFraction.from(0.6152, 999));
assertFraction(769, 1250, BigFraction.from(0.6152, 9999));
// MATH-996
@@ -155,11 +162,11 @@ public class BigFractionTest {
public void testEpsilonLimitConstructor() throws Exception {
assertFraction(2, 5, BigFraction.from(0.4, 1.0e-5, 100));
- assertFraction(3, 5, BigFraction.from(0.6152, 0.02, 100));
- assertFraction(8, 13, BigFraction.from(0.6152, 1.0e-3, 100));
- assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-4, 100));
- assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-5, 100));
- assertFraction(510, 829, BigFraction.from(0.6152, 1.0e-6, 100));
+ assertFraction(3, 5, BigFraction.from(0.6152, 0.02, 100));
+ assertFraction(8, 13, BigFraction.from(0.6152, 1.0e-3, 100));
+ assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-4, 100));
+ assertFraction(251, 408, BigFraction.from(0.6152, 1.0e-5, 100));
+ assertFraction(510, 829, BigFraction.from(0.6152, 1.0e-6, 100));
assertFraction(769, 1250, BigFraction.from(0.6152, 1.0e-7, 100));
}
@@ -197,18 +204,17 @@ public class BigFractionTest {
@Test
public void testDoubleValue() {
- Assertions.assertEquals(0d, BigFraction.ZERO.doubleValue(), 0d);
-
assertDoubleValue(0.5, 1, 2);
assertDoubleValue(-0.5, -1, 2);
assertDoubleValue(-0.5, 1, -2);
assertDoubleValue(0.5, -1, -2);
assertDoubleValue(1.0 / 3.0, 1, 3);
+ Assertions.assertEquals(0.0, BigFraction.ZERO.doubleValue());
Assertions.assertEquals(0.0, ZERO_P.doubleValue());
Assertions.assertEquals(0.0, ZERO_N.doubleValue());
- //NUMBERS-120
+ // NUMBERS-120
assertDoubleValue(
2d - 0x1P-52,
1L << 54,
@@ -297,7 +303,7 @@ public class BigFractionTest {
final BigInteger pow401 = BigInteger.TEN.pow(401);
final BigInteger two = new BigInteger("2");
final BigFraction large = BigFraction.of(pow401.add(BigInteger.ONE),
- pow400.multiply(two));
+ pow400.multiply(two));
Assertions.assertEquals(5, large.doubleValue(), 1e-15);
}
@@ -309,7 +315,7 @@ public class BigFractionTest {
final BigInteger pow401 = BigInteger.TEN.pow(401);
final BigInteger two = new BigInteger("2");
final BigFraction large = BigFraction.of(pow401.add(BigInteger.ONE),
- pow400.multiply(two));
+ pow400.multiply(two));
Assertions.assertEquals(5, large.floatValue(), 1e-15);
}
@@ -320,7 +326,7 @@ public class BigFractionTest {
final BigInteger pow300 = BigInteger.TEN.pow(300);
final BigInteger pow330 = BigInteger.TEN.pow(330);
final BigFraction large = BigFraction.of(pow330.add(BigInteger.ONE),
- pow300);
+ pow300);
Assertions.assertEquals(1e30, large.doubleValue(), 1e-15);
@@ -350,23 +356,23 @@ public class BigFractionTest {
final BigInteger pow30 = BigInteger.TEN.pow(30);
final BigInteger pow40 = BigInteger.TEN.pow(40);
final BigFraction large = BigFraction.of(pow40.add(BigInteger.ONE),
- pow30);
+ pow30);
Assertions.assertEquals(1e10f, large.floatValue(), 1e-15);
}
@Test
public void testFloatValue() {
- Assertions.assertEquals(0.5f, BigFraction.of(1, 2).floatValue(), 0.0f);
- Assertions.assertEquals(0.5f, BigFraction.of(-1, -2).floatValue(), 0.0f);
- Assertions.assertEquals(-0.5f, BigFraction.of(-1, 2).floatValue(), 0.0f);
- Assertions.assertEquals(-0.5f, BigFraction.of(1, -2).floatValue(), 0.0f);
+ Assertions.assertEquals(0.5f, BigFraction.of(1, 2).floatValue());
+ Assertions.assertEquals(0.5f, BigFraction.of(-1, -2).floatValue());
+ Assertions.assertEquals(-0.5f, BigFraction.of(-1, 2).floatValue());
+ Assertions.assertEquals(-0.5f, BigFraction.of(1, -2).floatValue());
final float e = 1f / 3f;
- Assertions.assertEquals(e, BigFraction.of(1, 3).floatValue(), 0.0f);
- Assertions.assertEquals(e, BigFraction.of(-1, -3).floatValue(), 0.0f);
- Assertions.assertEquals(-e, BigFraction.of(-1, 3).floatValue(), 0.0f);
- Assertions.assertEquals(-e, BigFraction.of(1, -3).floatValue(), 0.0f);
+ Assertions.assertEquals(e, BigFraction.of(1, 3).floatValue());
+ Assertions.assertEquals(e, BigFraction.of(-1, -3).floatValue());
+ Assertions.assertEquals(-e, BigFraction.of(-1, 3).floatValue());
+ Assertions.assertEquals(-e, BigFraction.of(1, -3).floatValue());
Assertions.assertEquals(0.0f, ZERO_P.floatValue());
Assertions.assertEquals(0.0f, ZERO_N.floatValue());
@@ -458,42 +464,18 @@ public class BigFractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
- final BigFraction f0 = BigFraction.of(-17 - 2 * 13 * 2, 13 * 13 * 17 * 2 * 2);
- Assertions.assertThrows(NullPointerException.class,
- () -> f0.add((BigFraction) null)
- );
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigFraction) null));
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.add((BigInteger) null));
BigFraction f1 = BigFraction.of(Integer.MAX_VALUE - 1, 1);
- BigFraction f = f1.add(BigInteger.ONE);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
+ assertFraction(Integer.MAX_VALUE, 1, f1.add(1));
+ assertFraction(Integer.MAX_VALUE, 1, f1.add(1L));
+ assertFraction(Integer.MAX_VALUE, 1, f1.add(BigInteger.ONE));
- f = f.add(BigInteger.ZERO);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
-
- f1 = BigFraction.of(Integer.MAX_VALUE - 1, 1);
- f = f1.add(1);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
-
- f = f.add(0);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
-
- f1 = BigFraction.of(Integer.MAX_VALUE - 1, 1);
- f = f1.add(1L);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
-
- f = f.add(0L);
- Assertions.assertEquals(Integer.MAX_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
-
- // Special case when numerator signum is zero
- f = BigFraction.ZERO.add(BigInteger.TEN);
- Assertions.assertEquals(10, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
+ // Special cases
+ BigFraction f2 = BigFraction.of(1, 2);
+ assertFraction(1, 2, f2.add(BigInteger.ZERO));
+ assertFraction(12, 1, BigFraction.ZERO.add(BigInteger.valueOf(12)));
}
@Test
@@ -504,38 +486,30 @@ public class BigFractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
- Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigInteger.ZERO));
- Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigFraction.ZERO));
-
- BigFraction f1;
- BigFraction f2;
-
- f1 = BigFraction.of(0, 5);
- f2 = BigFraction.of(2, 7);
- BigFraction f = f1.divide(f2);
- Assertions.assertEquals(BigFraction.ZERO, f);
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigFraction) null));
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.divide((BigInteger) null));
- final BigFraction f3 = BigFraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(NullPointerException.class,
- () -> f3.divide((BigFraction) null)
- );
+ Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigFraction.ZERO));
+ Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(0));
+ Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(0L));
+ Assertions.assertThrows(FractionException.class, () -> BigFraction.of(1, 2).divide(BigInteger.ZERO));
- f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- f = f1.divide(BigInteger.valueOf(Integer.MIN_VALUE));
- Assertions.assertEquals(-Integer.MAX_VALUE, f.getDenominatorAsInt());
- Assertions.assertEquals(-1, f.getNumeratorAsInt());
+ BigFraction f1 = BigFraction.of(0, 5);
+ Assertions.assertEquals(BigFraction.ZERO, f1.divide(BigFraction.of(2, 7)));
+ Assertions.assertEquals(BigFraction.ZERO, f1.divide(11));
+ Assertions.assertEquals(BigFraction.ZERO, f1.divide(11L));
+ Assertions.assertEquals(BigFraction.ZERO, f1.divide(BigInteger.valueOf(11)));
- f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- f = f1.divide(Integer.MIN_VALUE);
- Assertions.assertEquals(-Integer.MAX_VALUE, f.getDenominatorAsInt());
- Assertions.assertEquals(-1, f.getNumeratorAsInt());
+ f1 = BigFraction.of(6, 35);
+ assertFraction(2, 175, f1.divide(15));
+ assertFraction(2, 175, f1.divide(15L));
+ assertFraction(2, 175, f1.divide(BigInteger.valueOf(15)));
+ // Special cases
f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- f = f1.divide((long) Integer.MIN_VALUE);
- Assertions.assertEquals(-Integer.MAX_VALUE, f.getDenominatorAsInt());
- Assertions.assertEquals(-1, f.getNumeratorAsInt());
-
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.of(0, 3).divide(BigInteger.valueOf(11)));
+ assertFraction(-1, -Integer.MAX_VALUE, f1.divide(Integer.MIN_VALUE));
+ assertFraction(-1, -Integer.MAX_VALUE, f1.divide((long) Integer.MIN_VALUE));
+ assertFraction(-1, -Integer.MAX_VALUE, f1.divide(BigInteger.valueOf(Integer.MIN_VALUE)));
}
@Test
@@ -546,23 +520,43 @@ public class BigFractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
- BigFraction f2 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
- BigFraction f = f2.multiply(Integer.MAX_VALUE);
- Assertions.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigFraction) null));
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigInteger) null));
- f = f2.multiply((long) Integer.MAX_VALUE);
- Assertions.assertEquals(Integer.MIN_VALUE, f.getNumeratorAsInt());
- Assertions.assertEquals(1, f.getDenominatorAsInt());
+ BigFraction f1 = BigFraction.of(6, 35);
+ assertFraction(18, 7, f1.multiply(15));
+ assertFraction(18, 7, f1.multiply((long) 15));
+ assertFraction(18, 7, f1.multiply(BigInteger.valueOf(15)));
- Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.multiply((BigFraction) null));
+ f1 = BigFraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ assertFraction(Integer.MIN_VALUE, 1, f1.multiply(Integer.MAX_VALUE));
+ assertFraction(Integer.MIN_VALUE, 1, f1.multiply((long) Integer.MAX_VALUE));
+ assertFraction(Integer.MIN_VALUE, 1, f1.multiply(BigInteger.valueOf(Integer.MAX_VALUE)));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(BigInteger.ONE));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(BigInteger.ZERO));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(1));
+ Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(42));
+ Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(42L));
+ Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(BigInteger.valueOf(42)));
Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(0));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ZERO.multiply(1L));
Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(0L));
+ Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.multiply(BigInteger.ZERO));
+ }
+
+ @Test
+ public void testPow() {
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powFractionTestCases()) {
+ BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int exponent = testCase.secondOperand;
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow((long) exponent));
+ assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(BigInteger.valueOf(exponent)));
+ }
+
+ // Note: BigInteger magnitude is limited to 2^Integer.MAX_VALUE exclusive
+ // in the reference implementation (up to at least JDK 14).
+ Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(Integer.MAX_VALUE));
+ Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(Integer.MAX_VALUE));
+ Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(-Integer.MAX_VALUE));
+ Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(-Integer.MAX_VALUE));
}
@Test
@@ -573,14 +567,17 @@ public class BigFractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
- BigFraction f = BigFraction.of(1, 1);
- Assertions.assertThrows(NullPointerException.class, () -> f.subtract((BigFraction) null));
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigFraction) null));
+ Assertions.assertThrows(NullPointerException.class, () -> BigFraction.ONE.subtract((BigInteger) null));
- Assertions.assertEquals(BigFraction.ONE, BigFraction.ONE.subtract(BigInteger.ZERO));
- Assertions.assertEquals(BigFraction.of(-1), BigFraction.ZERO.subtract(BigInteger.ONE));
- Assertions.assertEquals(BigFraction.of(-2), BigFraction.ZERO.subtract(2));
- Assertions.assertEquals(BigFraction.of(-123), BigFraction.ZERO.subtract(123L));
- Assertions.assertEquals(BigFraction.of(-7, 3), BigFraction.of(2, 3).subtract(BigInteger.valueOf(3)));
+ assertFraction(-3, 1, BigFraction.ZERO.subtract(3));
+ assertFraction(-3, 1, BigFraction.ZERO.subtract(3L));
+ assertFraction(-3, 1, BigFraction.ZERO.subtract(BigInteger.valueOf(3)));
+
+ BigFraction f1 = BigFraction.of(2, 3);
+ assertFraction(-7, 3, f1.subtract(3));
+ assertFraction(-7, 3, f1.subtract(3L));
+ assertFraction(-7, 3, f1.subtract(BigInteger.valueOf(3)));
}
@Test
@@ -653,35 +650,6 @@ public class BigFractionTest {
}
@Test
- public void testPow() {
- for (CommonTestCases.BinaryIntOperatorTestCase testCase : CommonTestCases.powFractionTestCases()) {
- BigFraction f1 = BigFraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
- int exponent = testCase.secondOperand;
- assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.pow(exponent));
- }
-
- // Note: BigInteger magnitude is limited to 2^Integer.MAX_VALUE exclusive
- // in the reference implementation (up to at least JDK 14).
- Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(Integer.MAX_VALUE));
- Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(Integer.MAX_VALUE));
- Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(2).pow(-Integer.MAX_VALUE));
- Assertions.assertThrows(ArithmeticException.class, () -> BigFraction.of(1, 2).pow(-Integer.MAX_VALUE));
-
- Assertions.assertEquals(BigFraction.of(8192, 1594323), BigFraction.of(2, 3).pow(13));
- Assertions.assertEquals(BigFraction.of(8192, 1594323), BigFraction.of(2, 3).pow(13L));
- Assertions.assertEquals(BigFraction.of(8192, 1594323), BigFraction.of(2, 3).pow(BigInteger.valueOf(13L)));
- Assertions.assertEquals(BigFraction.ONE, BigFraction.of(2, 3).pow(0));
- Assertions.assertEquals(BigFraction.ONE, BigFraction.of(2, 3).pow(0L));
- Assertions.assertEquals(BigFraction.ONE, BigFraction.of(2, 3).pow(BigInteger.valueOf(0L)));
- Assertions.assertEquals(BigFraction.of(1594323, 8192), BigFraction.of(2, 3).pow(-13));
- Assertions.assertEquals(BigFraction.of(1594323, 8192), BigFraction.of(2, 3).pow(-13L));
- Assertions.assertEquals(BigFraction.of(1594323, 8192), BigFraction.of(2, 3).pow(BigInteger.valueOf(-13L)));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.of(0, 5).pow(123));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.of(0, 5).pow(123L));
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.of(0, 5).pow(new BigInteger("112233445566778899")));
- }
-
- @Test
public void testMath340() {
BigFraction fractionA = BigFraction.from(0.00131);
BigFraction fractionB = BigFraction.from(.37).reciprocal();
@@ -692,6 +660,16 @@ public class BigFractionTest {
}
@Test
+ public void testAdditiveNeutral() {
+ Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.zero());
+ }
+
+ @Test
+ public void testMultiplicativeNeutral() {
+ Assertions.assertEquals(BigFraction.ONE, BigFraction.ZERO.one());
+ }
+
+ @Test
public void testSerial() {
BigFraction[] fractions = {
BigFraction.of(3, 4), BigFraction.ONE, BigFraction.ZERO,
@@ -699,20 +677,12 @@ public class BigFractionTest {
BigFraction.of(-5, 2)
};
for (BigFraction fraction : fractions) {
- Assertions.assertEquals(fraction, TestUtils.serializeAndRecover(fraction));
+ Assertions.assertEquals(fraction,
+ TestUtils.serializeAndRecover(fraction));
}
}
@Test
- public void testAdditiveNeutral() {
- Assertions.assertEquals(BigFraction.ZERO, BigFraction.ONE.zero());
- }
- @Test
- public void testMultiplicativeNeutral() {
- Assertions.assertEquals(BigFraction.ONE, BigFraction.ZERO.one());
- }
-
- @Test
public void testToString() {
Assertions.assertEquals("0", BigFraction.of(0, 3).toString());
Assertions.assertEquals("0", BigFraction.of(0, -3).toString());
@@ -725,20 +695,38 @@ public class BigFractionTest {
@Test
public void testParse() {
String[] validExpressions = new String[] {
- "3",
"1 / 2",
"-1 / 2",
"1 / -2",
"-1 / -2",
+ "01 / 2",
+ "01 / 02",
+ "-01 / 02",
+ "01 / -02",
+ "15 / 16",
+ "-2 / 3",
+ "8 / 7",
+ "5",
+ "-3",
+ "-3",
"2147,483,647 / 2,147,483,648", //over largest int value
"9,223,372,036,854,775,807 / 9,223,372,036,854,775,808" //over largest long value
};
BigFraction[] fractions = {
- BigFraction.of(3),
BigFraction.of(1, 2),
BigFraction.of(-1, 2),
BigFraction.of(1, -2),
BigFraction.of(-1, -2),
+ BigFraction.of(1, 2),
+ BigFraction.of(1, 2),
+ BigFraction.of(-1, 2),
+ BigFraction.of(1, -2),
+ BigFraction.of(15, 16),
+ BigFraction.of(-2, 3),
+ BigFraction.of(8, 7),
+ BigFraction.of(5, 1),
+ BigFraction.of(-3, 1),
+ BigFraction.of(3, -1),
BigFraction.of(2147483647, 2147483648L),
BigFraction.of(new BigInteger("9223372036854775807"),
new BigInteger("9223372036854775808"))
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 9f663e3..d1916f6 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -23,6 +23,7 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
+ * Tests for {@link Fraction}.
*/
public class FractionTest {
@@ -31,7 +32,7 @@ public class FractionTest {
/** The zero representation with negative denominator. */
private static final Fraction ZERO_N = Fraction.of(0, -1);
- private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
+ private static void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
Assertions.assertEquals(expectedNumerator, actual.getNumerator());
Assertions.assertEquals(expectedDenominator, actual.getDenominator());
Assertions.assertEquals(
@@ -39,6 +40,11 @@ public class FractionTest {
actual.signum());
}
+ private static void assertDoubleValue(double expected, int numerator, int denominator) {
+ Fraction f = Fraction.of(numerator, denominator);
+ Assertions.assertEquals(expected, f.doubleValue());
+ }
+
@Test
public void testConstructor() {
for (CommonTestCases.UnaryOperatorTestCase testCase : CommonTestCases.numDenConstructorTestCases()) {
@@ -79,18 +85,6 @@ public class FractionTest {
}
}
- @Test
- public void testDoubleConstructorThrowsWithNonFinite() {
- final double eps = 1e-5;
- final int maxIterations = Integer.MAX_VALUE;
- final int maxDenominator = Integer.MAX_VALUE;
- for (final double value : new double[] {Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}) {
- Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value));
- Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value, eps, maxIterations));
- Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value, maxDenominator));
- }
- }
-
// MATH-181
@Test
public void testDigitLimitConstructor() throws Exception {
@@ -108,6 +102,18 @@ public class FractionTest {
}
@Test
+ public void testDoubleConstructorThrowsWithNonFinite() {
+ final double eps = 1e-5;
+ final int maxIterations = Integer.MAX_VALUE;
+ final int maxDenominator = Integer.MAX_VALUE;
+ for (final double value : new double[] {Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY}) {
+ Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value, eps, maxIterations));
+ Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(value, maxDenominator));
+ }
+ }
+
+ @Test
public void testIntegerOverflow() {
checkIntegerOverflow(0.75000000001455192);
checkIntegerOverflow(1.0e10);
@@ -135,14 +141,23 @@ public class FractionTest {
@Test
public void testCompareTo() {
- Fraction first = Fraction.of(1, 2);
- Fraction second = Fraction.of(1, 3);
- Fraction third = Fraction.of(1, 2);
-
- Assertions.assertEquals(0, first.compareTo(first));
- Assertions.assertEquals(0, first.compareTo(third));
- Assertions.assertEquals(1, first.compareTo(second));
- Assertions.assertEquals(-1, second.compareTo(first));
+ final Fraction a = Fraction.of(1, 2);
+ final Fraction b = Fraction.of(1, 3);
+ final Fraction c = Fraction.of(1, 2);
+ final Fraction d = Fraction.of(-1, 2);
+ final Fraction e = Fraction.of(1, -2);
+
+ Assertions.assertEquals(0, a.compareTo(a));
+ Assertions.assertEquals(0, a.compareTo(c));
+ Assertions.assertEquals(1, a.compareTo(b));
+ Assertions.assertEquals(-1, b.compareTo(a));
+ Assertions.assertEquals(-1, d.compareTo(a));
+ Assertions.assertEquals(1, a.compareTo(d));
+// Assertions.assertEquals(-1, e.compareTo(a));
+// Assertions.assertEquals(1, a.compareTo(e));
+ Assertions.assertEquals(0, d.compareTo(e));
+
+ Assertions.assertEquals(0, Fraction.of(0, 3).compareTo(Fraction.of(0, -2)));
// these two values are different approximations of PI
// the first one is approximately PI - 3.07e-18
@@ -158,23 +173,29 @@ public class FractionTest {
@Test
public void testDoubleValue() {
- Fraction first = Fraction.of(1, 2);
- Fraction second = Fraction.of(1, 3);
-
- Assertions.assertEquals(0.5, first.doubleValue(), 0.0);
- Assertions.assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
+ assertDoubleValue(0.5, 1, 2);
+ assertDoubleValue(-0.5, -1, 2);
+ assertDoubleValue(-0.5, 1, -2);
+ assertDoubleValue(0.5, -1, -2);
+ assertDoubleValue(1.0 / 3.0, 1, 3);
+ Assertions.assertEquals(0.0, Fraction.ZERO.doubleValue());
Assertions.assertEquals(0.0, ZERO_P.doubleValue());
Assertions.assertEquals(-0.0, ZERO_N.doubleValue());
}
@Test
public void testFloatValue() {
- Fraction first = Fraction.of(1, 2);
- Fraction second = Fraction.of(1, 3);
+ Assertions.assertEquals(0.5f, Fraction.of(1, 2).floatValue());
+ Assertions.assertEquals(0.5f, Fraction.of(-1, -2).floatValue());
+ Assertions.assertEquals(-0.5f, Fraction.of(-1, 2).floatValue());
+ Assertions.assertEquals(-0.5f, Fraction.of(1, -2).floatValue());
- Assertions.assertEquals(0.5f, first.floatValue(), 0.0f);
- Assertions.assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
+ final float e = 1f / 3f;
+ Assertions.assertEquals(e, Fraction.of(1, 3).floatValue());
+ Assertions.assertEquals(e, Fraction.of(-1, -3).floatValue());
+ Assertions.assertEquals(-e, Fraction.of(-1, 3).floatValue());
+ Assertions.assertEquals(-e, Fraction.of(1, -3).floatValue());
Assertions.assertEquals(0.0f, ZERO_P.floatValue());
Assertions.assertEquals(-0.0f, ZERO_N.floatValue());
@@ -182,11 +203,15 @@ public class FractionTest {
@Test
public void testIntValue() {
- Fraction first = Fraction.of(1, 2);
- Fraction second = Fraction.of(3, 2);
+ Assertions.assertEquals(0, Fraction.of(1, 2).intValue());
+ Assertions.assertEquals(0, Fraction.of(-1, -2).intValue());
+ Assertions.assertEquals(0, Fraction.of(-1, 2).intValue());
+ Assertions.assertEquals(0, Fraction.of(1, -2).intValue());
- Assertions.assertEquals(0, first.intValue());
- Assertions.assertEquals(1, second.intValue());
+ Assertions.assertEquals(1, Fraction.of(3, 2).intValue());
+ Assertions.assertEquals(1, Fraction.of(-3, -2).intValue());
+ Assertions.assertEquals(-1, Fraction.of(-3, 2).intValue());
+ Assertions.assertEquals(-1, Fraction.of(3, -2).intValue());
Assertions.assertEquals(0, ZERO_P.intValue());
Assertions.assertEquals(0, ZERO_N.intValue());
@@ -194,11 +219,15 @@ public class FractionTest {
@Test
public void testLongValue() {
- Fraction first = Fraction.of(1, 2);
- Fraction second = Fraction.of(3, 2);
+ Assertions.assertEquals(0L, Fraction.of(1, 2).longValue());
+ Assertions.assertEquals(0L, Fraction.of(-1, -2).longValue());
+ Assertions.assertEquals(0L, Fraction.of(-1, 2).longValue());
+ Assertions.assertEquals(0L, Fraction.of(1, -2).longValue());
- Assertions.assertEquals(0L, first.longValue());
- Assertions.assertEquals(1L, second.longValue());
+ Assertions.assertEquals(1L, Fraction.of(3, 2).longValue());
+ Assertions.assertEquals(1L, Fraction.of(-3, -2).longValue());
+ Assertions.assertEquals(-1L, Fraction.of(-3, 2).longValue());
+ Assertions.assertEquals(-1L, Fraction.of(3, -2).longValue());
Assertions.assertEquals(0L, ZERO_P.longValue());
Assertions.assertEquals(0L, ZERO_N.longValue());
@@ -206,6 +235,7 @@ public class FractionTest {
@Test
public void testConstructorDouble() {
+ assertFraction(0, 1, Fraction.from(0.0));
assertFraction(1, 2, Fraction.from(0.5));
assertFraction(1, 3, Fraction.from(1.0 / 3.0));
assertFraction(17, 100, Fraction.from(17.0 / 100.0));
@@ -214,6 +244,9 @@ public class FractionTest {
assertFraction(-1, 3, Fraction.from(-1.0 / 3.0));
assertFraction(-17, 100, Fraction.from(17.0 / -100.0));
assertFraction(-317, 100, Fraction.from(-317.0 / 100.0));
+ for (double v : new double[] {Double.NaN, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}) {
+ Assertions.assertThrows(IllegalArgumentException.class, () -> Fraction.from(v));
+ }
}
@Test
@@ -252,13 +285,8 @@ public class FractionTest {
Fraction f = Fraction.of(testCase.operandNumerator, testCase.operandDenominator);
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f.negate());
}
- }
- /**
- * Test special cases of negation that differ from BigFraction.
- */
- @Test
- public void testNegateMinValue() {
+ // Test special cases of negation that differ from BigFraction.
final Fraction one = Fraction.of(Integer.MIN_VALUE, Integer.MIN_VALUE);
assertFraction(-1, 1, one.negate());
// Special case where the negation of the numerator is not possible.
@@ -274,43 +302,40 @@ public class FractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(f2));
}
- Fraction f1 = Fraction.of(Integer.MAX_VALUE - 1, 1);
- Fraction f2 = f1.add(1);
- assertFraction(Integer.MAX_VALUE, 1, f2);
+ Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
- final Fraction f3 = Fraction.of(-17 - 2 * 13 * 2, 13 * 13 * 17 * 2 * 2);
- Assertions.assertThrows(NullPointerException.class,
- () -> f3.add(null)
- );
+ Fraction f1 = Fraction.of(Integer.MAX_VALUE - 1, 1);
+ assertFraction(Integer.MAX_VALUE, 1, f1.add(1));
- final Fraction f4 = Fraction.of(Integer.MAX_VALUE, 1);
+ // Special cases
+ final Fraction f3 = Fraction.of(Integer.MAX_VALUE, 1);
Assertions.assertThrows(ArithmeticException.class,
() -> {
- Fraction f = f4.add(Fraction.ONE); // should overflow
+ Fraction f = f3.add(Fraction.ONE); // should overflow
Assertions.fail("expecting ArithmeticException but got: " + f.toString());
}
);
// denominator should not be a multiple of 2 or 3 to trigger overflow
- final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 5);
- final Fraction f6 = Fraction.of(-1, 5);
+ final Fraction f4 = Fraction.of(Integer.MIN_VALUE, 5);
+ final Fraction f5 = Fraction.of(-1, 5);
Assertions.assertThrows(ArithmeticException.class,
() -> {
- Fraction f = f5.add(f6); // should overflow
+ Fraction f = f4.add(f5); // should overflow
Assertions.fail("expecting ArithmeticException but got: " + f.toString());
}
);
- final Fraction f7 = Fraction.of(-Integer.MAX_VALUE, 1);
+ final Fraction f6 = Fraction.of(-Integer.MAX_VALUE, 1);
Assertions.assertThrows(ArithmeticException.class,
- () -> f7.add(f7)
+ () -> f6.add(f6)
);
- final Fraction f8 = Fraction.of(3, 327680);
- final Fraction f9 = Fraction.of(2, 59049);
+ final Fraction f7 = Fraction.of(3, 327680);
+ final Fraction f8 = Fraction.of(2, 59049);
Assertions.assertThrows(ArithmeticException.class,
() -> {
- Fraction f = f8.add(f9); // should overflow
+ Fraction f = f7.add(f8); // should overflow
Assertions.fail("expecting ArithmeticException but got: " + f.toString());
}
);
@@ -324,35 +349,28 @@ public class FractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(f2));
}
- final Fraction f1 = Fraction.of(3, 5);
- final Fraction f2 = Fraction.ZERO;
- Assertions.assertThrows(FractionException.class,
- () -> f1.divide(f2)
- );
+ Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.divide((Fraction) null));
- Fraction f3 = Fraction.of(0, 5);
- Fraction f4 = Fraction.of(2, 7);
- Fraction f = f3.divide(f4);
- Assertions.assertEquals(Fraction.ZERO, f);
+ Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(Fraction.ZERO));
+ Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(0));
- final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(NullPointerException.class,
- () -> f5.divide(null)
- );
+ Fraction f1 = Fraction.of(0, 5);
+ Assertions.assertEquals(Fraction.ZERO, f1.divide(Fraction.of(2, 7)));
+ Assertions.assertEquals(Fraction.ZERO, f1.divide(11));
- final Fraction f6 = Fraction.of(1, Integer.MAX_VALUE);
+ f1 = Fraction.of(6, 35);
+ assertFraction(2, 175, f1.divide(15));
+
+ // Special cases
+ final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
Assertions.assertThrows(ArithmeticException.class,
- () -> f6.divide(f6.reciprocal()) // should overflow
+ () -> f3.divide(f3.reciprocal()) // should overflow
);
- final Fraction f7 = Fraction.of(1, -Integer.MAX_VALUE);
+ final Fraction f4 = Fraction.of(1, -Integer.MAX_VALUE);
Assertions.assertThrows(ArithmeticException.class,
- () -> f7.divide(f7.reciprocal()) // should overflow
+ () -> f4.divide(f4.reciprocal()) // should overflow
);
-
- Fraction f8 = Fraction.of(6, 35);
- Fraction f9 = f8.divide(15);
- assertFraction(2, 175, f9);
}
@Test
@@ -363,18 +381,17 @@ public class FractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(f2));
}
- final Fraction f0 = Fraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(NullPointerException.class,
- () -> f0.multiply(null)
- );
+ Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.multiply((Fraction) null));
Fraction f1 = Fraction.of(6, 35);
- Fraction f = f1.multiply(15);
- assertFraction(18, 7, f);
+ assertFraction(18, 7, f1.multiply(15));
+
+ f1 = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
+ assertFraction(Integer.MIN_VALUE, 1, f1.multiply(Integer.MAX_VALUE));
// Test zero with multiply by integer
Assertions.assertEquals(Fraction.ZERO, Fraction.ZERO.multiply(42));
- Assertions.assertEquals(Fraction.ZERO, Fraction.of(1, 3).multiply(0));
+ Assertions.assertEquals(Fraction.ZERO, Fraction.ONE.multiply(0));
}
@Test
@@ -399,14 +416,12 @@ public class FractionTest {
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(f2));
}
- final Fraction f0 = Fraction.of(1, 1);
- Assertions.assertThrows(NullPointerException.class,
- () -> f0.subtract(null)
- );
+ Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
- Fraction f1 = Fraction.of(Integer.MAX_VALUE, 1);
- Fraction f2 = f1.subtract(1);
- assertFraction(Integer.MAX_VALUE - 1, 1, f2);
+ assertFraction(-3, 1, Fraction.ZERO.subtract(3));
+
+ Fraction f1 = Fraction.of(2, 3);
+ assertFraction(-7, 3, f1.subtract(3));
final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
@@ -520,22 +535,13 @@ public class FractionTest {
public void testAdditiveNeutral() {
Assertions.assertEquals(Fraction.ZERO, Fraction.ONE.zero());
}
+
@Test
public void testMultiplicativeNeutral() {
Assertions.assertEquals(Fraction.ONE, Fraction.ZERO.one());
}
@Test
- public void testToString() {
- Assertions.assertEquals("0", Fraction.of(0, 3).toString());
- Assertions.assertEquals("0", Fraction.of(0, -3).toString());
- Assertions.assertEquals("3", Fraction.of(6, 2).toString());
- Assertions.assertEquals("2 / 3", Fraction.of(18, 27).toString());
- Assertions.assertEquals("-10 / 11", Fraction.of(-10, 11).toString());
- Assertions.assertEquals("10 / -11", Fraction.of(10, -11).toString());
- }
-
- @Test
public void testSerial() {
Fraction[] fractions = {
Fraction.of(3, 4), Fraction.ONE, Fraction.ZERO,
@@ -549,6 +555,16 @@ public class FractionTest {
}
@Test
+ public void testToString() {
+ Assertions.assertEquals("0", Fraction.of(0, 3).toString());
+ Assertions.assertEquals("0", Fraction.of(0, -3).toString());
+ Assertions.assertEquals("3", Fraction.of(6, 2).toString());
+ Assertions.assertEquals("2 / 3", Fraction.of(18, 27).toString());
+ Assertions.assertEquals("-10 / 11", Fraction.of(-10, 11).toString());
+ Assertions.assertEquals("10 / -11", Fraction.of(10, -11).toString());
+ }
+
+ @Test
public void testParse() {
String[] validExpressions = new String[] {
"1 / 2",
[commons-numbers] 21/26: FractionTest: Create test cases for
arithmetic overflow
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 1e789e0538dc9c5ab37eadafa0cb365c526981f7
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 21:24:18 2020 +0100
FractionTest: Create test cases for arithmetic overflow
---
.../commons/numbers/fraction/FractionTest.java | 223 ++++++++++++++-------
1 file changed, 150 insertions(+), 73 deletions(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 7042e82..ff085c0 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -16,9 +16,12 @@
*/
package org.apache.commons.numbers.fraction;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import org.apache.commons.numbers.core.TestUtils;
-
+import org.apache.commons.numbers.fraction.CommonTestCases.BinaryIntOperatorTestCase;
+import org.apache.commons.numbers.fraction.CommonTestCases.BinaryOperatorTestCase;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -307,30 +310,18 @@ public class FractionTest {
int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.add(i2));
}
+ for (CommonTestCases.BinaryOperatorTestCase testCase : addFractionOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.add(f2));
+ }
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : addIntOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.add(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
-
- // Special cases
- final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
- final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f3.add(f4));
-
- // denominator should not be a multiple of 2 or 3 to trigger overflow
- final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 5);
- final Fraction f6 = Fraction.of(-1, 5);
- Assertions.assertThrows(ArithmeticException.class, () -> f5.add(f6));
-
- final Fraction f7 = Fraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f7.add(Fraction.ONE.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f7.add(-1));
-
- final Fraction f8 = Fraction.of(Integer.MAX_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f8.add(Fraction.ONE));
- Assertions.assertThrows(ArithmeticException.class, () -> f8.add(1));
-
- final Fraction f9 = Fraction.of(3, 327680);
- final Fraction f10 = Fraction.of(2, 59049);
- Assertions.assertThrows(ArithmeticException.class, () -> f9.add(f10));
}
@Test
@@ -345,25 +336,21 @@ public class FractionTest {
int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.divide(i2));
}
+ for (CommonTestCases.BinaryOperatorTestCase testCase : divideByFractionOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.divide(f2));
+ }
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : divideByIntOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.divide(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.divide((Fraction) null));
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(Fraction.ZERO));
Assertions.assertThrows(FractionException.class, () -> Fraction.of(1, 2).divide(0));
-
- // Special cases for overflow
- final Fraction two = Fraction.of(2);
- final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
- Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(two));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(two.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(2));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.divide(-2));
-
- final Fraction f4 = Fraction.of(1, Integer.MIN_VALUE);
- Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(two));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(two.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(2));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.divide(-2));
}
@Test
@@ -378,22 +365,18 @@ public class FractionTest {
int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.multiply(i2));
}
+ for (CommonTestCases.BinaryOperatorTestCase testCase : multiplyByFractionOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.multiply(f2));
+ }
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : multiplyByIntOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.multiply(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.multiply((Fraction) null));
-
- // Special cases for overflow
- final Fraction two = Fraction.of(2);
- final Fraction f3 = Fraction.of(Integer.MAX_VALUE);
- Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(two));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(two.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(2));
- Assertions.assertThrows(ArithmeticException.class, () -> f3.multiply(-2));
-
- final Fraction f4 = Fraction.of(Integer.MIN_VALUE);
- Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(two));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(two.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(2));
- Assertions.assertThrows(ArithmeticException.class, () -> f4.multiply(-2));
}
@Test
@@ -422,30 +405,18 @@ public class FractionTest {
int i2 = testCase.secondOperand;
assertFraction(testCase.expectedNumerator, testCase.expectedDenominator, f1.subtract(i2));
}
+ for (CommonTestCases.BinaryOperatorTestCase testCase : subtractFractionOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ Fraction f2 = Fraction.of(testCase.secondOperandNumerator, testCase.secondOperandDenominator);
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.subtract(f2));
+ }
+ for (CommonTestCases.BinaryIntOperatorTestCase testCase : subtractIntOverflowTestCases()) {
+ Fraction f1 = Fraction.of(testCase.firstOperandNumerator, testCase.firstOperandDenominator);
+ int i2 = testCase.secondOperand;
+ Assertions.assertThrows(ArithmeticException.class, () -> f1.subtract(i2));
+ }
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
-
- // Special cases
- final Fraction f3 = Fraction.of(1, Integer.MAX_VALUE);
- final Fraction f4 = Fraction.of(1, Integer.MAX_VALUE - 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f3.subtract(f4));
-
- // denominator should not be a multiple of 2 or 3 to trigger overflow
- final Fraction f5 = Fraction.of(Integer.MIN_VALUE, 5);
- final Fraction f6 = Fraction.of(1, 5);
- Assertions.assertThrows(ArithmeticException.class, () -> f5.subtract(f6));
-
- final Fraction f7 = Fraction.of(Integer.MIN_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f7.subtract(Fraction.ONE));
- Assertions.assertThrows(ArithmeticException.class, () -> f7.subtract(1));
-
- final Fraction f8 = Fraction.of(Integer.MAX_VALUE, 1);
- Assertions.assertThrows(ArithmeticException.class, () -> f8.subtract(Fraction.ONE.negate()));
- Assertions.assertThrows(ArithmeticException.class, () -> f8.subtract(-1));
-
- final Fraction f9 = Fraction.of(3, 327680);
- final Fraction f10 = Fraction.of(2, 59049);
- Assertions.assertThrows(ArithmeticException.class, () -> f9.subtract(f10));
}
@Test
@@ -609,4 +580,110 @@ public class FractionTest {
final Fraction b = Fraction.of(2, Integer.MAX_VALUE);
assertFraction(1, Integer.MAX_VALUE, b.divide(2));
}
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#add(Fraction)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryOperatorTestCase> addFractionOverflowTestCases() {
+ List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 5, -1, 5, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, -1, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, 1, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(3, 327680, 2, 59049, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(1, 2, Integer.MIN_VALUE, -2, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#add(int)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryIntOperatorTestCase> addIntOverflowTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, -1, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, 1, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(1, 2, Integer.MIN_VALUE / -2, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#divide(Fraction)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryOperatorTestCase> divideByFractionOverflowTestCases() {
+ List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, -2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MIN_VALUE, 2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MIN_VALUE, -2, 1, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#divide(int)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryIntOperatorTestCase> divideByIntOverflowTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryIntOperatorTestCase(1, Integer.MAX_VALUE, 2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(1, Integer.MAX_VALUE, -2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(1, Integer.MIN_VALUE, 2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(1, Integer.MIN_VALUE, -2, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#multiply(Fraction)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryOperatorTestCase> multiplyByFractionOverflowTestCases() {
+ List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, 2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, -2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, 2, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, -2, 1, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#multiply(int)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryIntOperatorTestCase> multiplyByIntOverflowTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, 2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, -2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, 2, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, -2, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#subtract(Fraction)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryOperatorTestCase> subtractFractionOverflowTestCases() {
+ List<BinaryOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryOperatorTestCase(1, Integer.MAX_VALUE, 1, Integer.MAX_VALUE - 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 5, 1, 5, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MIN_VALUE, 1, 1, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(Integer.MAX_VALUE, 1, -1, 1, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(3, 327680, 2, 59049, 0, 0));
+ testCases.add(new BinaryOperatorTestCase(1, 2, Integer.MIN_VALUE, 2, 0, 0));
+ return testCases;
+ }
+
+ /**
+ * Defines test cases that cause overflow in {@link Fraction#subtract(int)}.
+ * @return a list of test cases
+ */
+ private static List<BinaryIntOperatorTestCase> subtractIntOverflowTestCases() {
+ List<BinaryIntOperatorTestCase> testCases = new ArrayList<>();
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MIN_VALUE, 1, 1, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(Integer.MAX_VALUE, 1, -1, 0, 0));
+ testCases.add(new BinaryIntOperatorTestCase(1, 2, Integer.MIN_VALUE / 2, 0, 0));
+ return testCases;
+ }
}
[commons-numbers] 13/26: Fraction: Optimise divide by fraction
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 6794743049740bf8088065cd296d117544ca0e8c
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 21:57:57 2020 +0100
Fraction: Optimise divide by fraction
The divide uses multiply by reciprocal. This can avoid the call to
reciprocal() by directly inverting the numerator and denominator. These
will already by in reduced form and thus this avoids the reduction
algorithm.
---
.../commons/numbers/fraction/BigFraction.java | 4 +++-
.../apache/commons/numbers/fraction/Fraction.java | 27 ++++++++++++++++++----
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
index 6a16541..6e1ea48 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/BigFraction.java
@@ -913,7 +913,9 @@ public final class BigFraction
if (isZero()) {
return ZERO;
}
- return multiply(value.reciprocal());
+ // Multiply by reciprocal
+ return new BigFraction(numerator.multiply(value.denominator),
+ denominator.multiply(value.numerator));
}
/**
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index d424045..6702950 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -615,13 +615,29 @@ public final class Fraction
if (value.isZero() || isZero()) {
return ZERO;
}
+ return multiply(value.numerator, value.denominator);
+ }
+ /**
+ * Multiply this fraction by the passed fraction decomposed into a numerator and
+ * denominator, returning the result in reduced form.
+ *
+ * <p>This is a utility method to be used by multiply and divide. The decomposed
+ * fraction arguments and this fraction are not checked for zero.
+ *
+ * @param num Fraction numerator.
+ * @param den Fraction denominator.
+ * @return {@code this * num / den}.
+ * @throws ArithmeticException if the resulting numerator or denominator cannot
+ * be represented in an {@code int}.
+ */
+ private Fraction multiply(int num, int den) {
// knuth 4.5.1
// Make sure we don't overflow unless the result *must* overflow.
- final int d1 = ArithmeticUtils.gcd(numerator, value.denominator);
- final int d2 = ArithmeticUtils.gcd(value.numerator, denominator);
- return new Fraction(Math.multiplyExact(numerator / d1, value.numerator / d2),
- Math.multiplyExact(denominator / d2, value.denominator / d1));
+ final int d1 = ArithmeticUtils.gcd(numerator, den);
+ final int d2 = ArithmeticUtils.gcd(num, denominator);
+ return new Fraction(Math.multiplyExact(numerator / d1, num / d2),
+ Math.multiplyExact(denominator / d2, den / d1));
}
/**
@@ -669,7 +685,8 @@ public final class Fraction
if (isZero()) {
return ZERO;
}
- return multiply(value.reciprocal());
+ // Multiply by reciprocal
+ return multiply(value.denominator, value.numerator);
}
/**
[commons-numbers] 16/26: Remove unused import
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 7d64af52fd2ed82e5410d6e7bbe202b153c1a381
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 22:12:15 2020 +0100
Remove unused import
---
.../src/test/java/org/apache/commons/numbers/fraction/FractionTest.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index f6b4842..18803d1 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.commons.numbers.fraction;
-import java.math.BigInteger;
import java.util.Arrays;
import org.apache.commons.numbers.core.TestUtils;
[commons-numbers] 20/26: Fraction: rename f to num (for numerator)
in add/subtract int
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit b0164fb6b185e3776a17af54c631ff76a74b4f66
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Apr 14 23:05:23 2020 +0100
Fraction: rename f to num (for numerator) in add/subtract int
---
.../main/java/org/apache/commons/numbers/fraction/Fraction.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index 7d025d9..a2ba424 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -482,8 +482,8 @@ public final class Fraction
*/
public Fraction add(final int value) {
// Convert to numerator with same effective denominator
- final long f = (long) value * denominator;
- return of(Math.toIntExact(numerator + f), denominator);
+ final long num = (long) value * denominator;
+ return of(Math.toIntExact(numerator + num), denominator);
}
/**
@@ -511,8 +511,8 @@ public final class Fraction
*/
public Fraction subtract(final int value) {
// Convert to numerator with same effective denominator
- final long f = (long) value * denominator;
- return of(Math.toIntExact(numerator - f), denominator);
+ final long num = (long) value * denominator;
+ return of(Math.toIntExact(numerator - num), denominator);
}
/**
[commons-numbers] 22/26: Fraction: test for zero in add/subtract int
Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git
commit 86e3b5f732eca7942984b63c2be7108d39605911
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Wed Apr 15 21:39:49 2020 +0100
Fraction: test for zero in add/subtract int
Added test cases with Integer.MIN_VALUE as this requires special
handling for subtract.
---
.../org/apache/commons/numbers/fraction/Fraction.java | 15 +++++++++++++++
.../org/apache/commons/numbers/fraction/FractionTest.java | 10 ++++++++++
2 files changed, 25 insertions(+)
diff --git a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
index a2ba424..e9b7199 100644
--- a/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
+++ b/commons-numbers-fraction/src/main/java/org/apache/commons/numbers/fraction/Fraction.java
@@ -481,6 +481,12 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction add(final int value) {
+ if (value == 0) {
+ return this;
+ }
+ if (isZero()) {
+ return new Fraction(value);
+ }
// Convert to numerator with same effective denominator
final long num = (long) value * denominator;
return of(Math.toIntExact(numerator + num), denominator);
@@ -510,6 +516,15 @@ public final class Fraction
* cannot be represented in an {@code int}.
*/
public Fraction subtract(final int value) {
+ if (value == 0) {
+ return this;
+ }
+ if (isZero()) {
+ // Special case for min value
+ return value == Integer.MIN_VALUE ?
+ new Fraction(Integer.MIN_VALUE, -1) :
+ new Fraction(-value);
+ }
// Convert to numerator with same effective denominator
final long num = (long) value * denominator;
return of(Math.toIntExact(numerator - num), denominator);
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index ff085c0..04ac063 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -322,6 +322,11 @@ public class FractionTest {
}
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
+
+ // Edge case
+ assertFraction(Integer.MIN_VALUE, -1, Fraction.ZERO.add(Fraction.of(Integer.MIN_VALUE, -1)));
+ assertFraction(Integer.MIN_VALUE, 1, Fraction.ZERO.add(Fraction.of(Integer.MIN_VALUE, 1)));
+ assertFraction(Integer.MIN_VALUE, 1, Fraction.ZERO.add(Integer.MIN_VALUE));
}
@Test
@@ -417,6 +422,11 @@ public class FractionTest {
}
Assertions.assertThrows(NullPointerException.class, () -> Fraction.ONE.add((Fraction) null));
+
+ // Edge case
+ assertFraction(Integer.MIN_VALUE, 1, Fraction.ZERO.subtract(Fraction.of(Integer.MIN_VALUE, -1)));
+ assertFraction(Integer.MIN_VALUE, -1, Fraction.ZERO.subtract(Fraction.of(Integer.MIN_VALUE, 1)));
+ assertFraction(Integer.MIN_VALUE, -1, Fraction.ZERO.subtract(Integer.MIN_VALUE));
}
@Test