/* * Universal Media Server, for streaming any media to DLNA * compatible renderers based on the http://www.ps3mediaserver.org. * Copyright (C) 2012 UMS developers. * * This program is a free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; version 2 * of the License only. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.pms.util; import java.math.BigDecimal; import java.math.BigInteger; import java.math.MathContext; import java.math.RoundingMode; import static org.junit.Assert.*; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; public class RationalTest { @Rule public final ExpectedException exception = ExpectedException.none(); @Test public void testDefaultConstructor() { assertEquals(Rational.ZERO, new Rational()); assertEquals(BigInteger.ZERO, Rational.ZERO.numerator); assertEquals(BigInteger.ONE, Rational.ZERO.denominator); assertEquals(BigInteger.ONE, Rational.ZERO.greatestCommonDivisor); assertEquals(BigInteger.ZERO, Rational.ZERO.reducedNumerator); assertEquals(BigInteger.ONE, Rational.ZERO.reducedDenominator); assertEquals("0", Rational.ZERO.stringValue); assertEquals("0", Rational.ZERO.reducedStringValue); assertEquals("0", Rational.ZERO.decimalStringValue); } @Test public void testDoubleConstructor() { assertEquals(0.342, new Rational(0.342).doubleValue(), 0.0); assertEquals(10000d, new Rational(10000d).doubleValue(), 0.0); assertEquals(1d/3, new Rational(1d/3).doubleValue(), 0.0); } @Test public void testBigDecimalConstructor() { assertEquals(0, new Rational(BigDecimal.ZERO).intValue()); assertEquals(BigDecimal.ONE, new Rational(BigDecimal.ONE).bigDecimalValue()); assertEquals(BigDecimal.valueOf(Long.MAX_VALUE), new Rational(BigDecimal.valueOf(Long.MAX_VALUE)).bigDecimalValue()); assertEquals(BigDecimal.valueOf(Long.MIN_VALUE), new Rational(BigDecimal.valueOf(Long.MIN_VALUE)).bigDecimalValue()); assertEquals( new BigDecimal("398427545234132213.4398023478543978313289043509400000000000000000000000000000000000000000000000000000000000000000000000"), new Rational(new BigDecimal("398427545234132213.43980234785439783132890435094")).bigDecimalValue() ); assertEquals( 0, new BigDecimal("398427545234132213.43980234785439783132890435094") .compareTo(new Rational(new BigDecimal("398427545234132213.43980234785439783132890435094")).bigDecimalValue()) ); } @Test public void testStringConstructor() { assertEquals(Rational.ZERO, new Rational("")); assertEquals(Rational.ZERO, new Rational((String) null)); assertEquals(4, new Rational("16 /4").intValue()); assertEquals(5, new Rational("20/4 ").intValue()); assertEquals(6d, new Rational(" 24 / 4").doubleValue(), 0.0); assertEquals(-6d, new Rational("-24/4").doubleValue(), 0.0); assertEquals(-6d, new Rational("24/ -4").doubleValue(), 0.0); assertEquals(6d, new Rational("-24/-4").doubleValue(), 0.0); assertEquals(0.5625, new Rational("9/16").doubleValue(), 0.0); assertEquals(-2194d, new Rational("-2194").doubleValue(), 0.0); } @Test public void testIntConstructor() { assertEquals(Rational.ZERO, new Rational(0)); assertEquals(-4096, new Rational(-4096).intValue()); assertEquals(Integer.MAX_VALUE, new Rational(Integer.MAX_VALUE).intValue()); assertEquals(Integer.MIN_VALUE, new Rational(Integer.MIN_VALUE).intValue()); } @Test public void testLongConstructor() { assertEquals(Rational.ZERO, new Rational(0L)); assertEquals(-4096, new Rational(-4096L).intValue()); assertEquals(Long.MAX_VALUE, new Rational(Long.MAX_VALUE).longValue()); assertEquals(Long.MIN_VALUE, new Rational(Long.MIN_VALUE).longValue()); assertEquals(BigInteger.ONE, new Rational(Long.MIN_VALUE).greatestCommonDivisor); assertEquals(BigInteger.ONE, new Rational(Long.MIN_VALUE).denominator); assertEquals(BigInteger.ONE, new Rational(Long.MIN_VALUE).reducedDenominator); } @Test public void testBigIntegerConstructor() { assertEquals(Rational.ZERO, new Rational(BigInteger.valueOf(0))); assertEquals("987933205489029348556903", new Rational(new BigInteger("987933205489029348556903")).stringValue); assertEquals(Long.MAX_VALUE, new Rational(BigInteger.valueOf(Long.MAX_VALUE)).longValue()); assertEquals(Long.MIN_VALUE, new Rational(BigInteger.valueOf(Long.MIN_VALUE)).longValue()); assertEquals(BigInteger.ONE, new Rational(BigInteger.valueOf(Long.MIN_VALUE)).greatestCommonDivisor); assertEquals(BigInteger.ONE, new Rational(BigInteger.valueOf(Long.MIN_VALUE)).denominator); assertEquals(BigInteger.ONE, new Rational(BigInteger.valueOf(Long.MIN_VALUE)).reducedDenominator); } @Test public void testTwoIntsConstructor() { assertEquals(Rational.ZERO, new Rational(0, 30)); assertEquals(-1, new Rational(-1, 30).signum()); assertEquals(-1, new Rational(1, -30).signum()); assertEquals(1, new Rational(-1, -30).signum()); assertEquals(Rational.ONE, new Rational(Integer.MAX_VALUE, Integer.MAX_VALUE)); assertEquals(Rational.ONE.negate(), new Rational(Integer.MAX_VALUE, -Integer.MAX_VALUE)); assertEquals("18/32", new Rational(18, 32).toString()); assertEquals("9/16", new Rational(18, 32).toReducedString()); assertEquals(0.5625, new Rational(18, 32).doubleValue(), 0.0); exception.expect(IllegalArgumentException.class); exception.expectMessage("denominator can't be zero"); assertEquals(Rational.ZERO, new Rational(0, 0)); } @Test public void testTwoLongsConstructor() { assertEquals(Rational.ZERO, new Rational(0L, 30L)); assertEquals(-1, new Rational(-1L, 30L).signum()); assertEquals(-1, new Rational(1L, -30L).signum()); assertEquals(1, new Rational(-1L, -30L).signum()); assertEquals(Rational.ONE, new Rational(Long.MAX_VALUE, Long.MAX_VALUE)); assertEquals(Rational.ONE.negate(), new Rational(Long.MAX_VALUE, -Long.MAX_VALUE)); assertEquals("36/64", new Rational(36L, 64L).toString()); assertEquals("9/16", new Rational(36L, 64L).toReducedString()); assertEquals(0.5625, new Rational(36L, 64L).doubleValue(), 0.0); exception.expect(IllegalArgumentException.class); exception.expectMessage("denominator can't be zero"); assertEquals(Rational.ZERO, new Rational(0L, 0L)); } @Test public void testTwoBigIntegersConstructor() { assertEquals(Rational.ZERO, new Rational(null, BigInteger.TEN)); assertEquals(-1, new Rational(BigInteger.ONE.negate(), BigInteger.valueOf(30)).signum()); assertEquals(-1, new Rational(BigInteger.ONE, BigInteger.valueOf(-30)).signum()); assertEquals(1, new Rational(BigInteger.ONE.negate(), BigInteger.valueOf(-30)).signum()); assertEquals(Rational.ONE, new Rational( BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(Long.MAX_VALUE)), BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(Long.MAX_VALUE)) )); assertEquals(Rational.ONE.negate(), new Rational( BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(Long.MAX_VALUE)), BigInteger.valueOf(Long.MAX_VALUE).multiply(BigInteger.valueOf(Long.MAX_VALUE)).negate() )); assertEquals( "42391158275216203514294433201/75362059155939917358745659024", new Rational(new BigInteger("42391158275216203514294433201"), new BigInteger("75362059155939917358745659024")).toString() ); assertEquals("9/16", new Rational( new BigInteger("42391158275216203514294433201"), new BigInteger("75362059155939917358745659024") ).toReducedString()); assertEquals(0.5625, new Rational( new BigInteger("42391158275216203514294433201"), new BigInteger("75362059155939917358745659024") ).doubleValue(), 0.0); exception.expect(IllegalArgumentException.class); exception.expectMessage("denominator can't be zero"); assertEquals(Rational.ZERO, new Rational(BigInteger.ZERO, null)); } @Test public void testMultiplyOperator() { assertEquals(new Rational(30), new Rational(5).multiply(6)); assertEquals(new Rational(60), new Rational(5).multiply(12L)); assertEquals(new Rational(90), new Rational(5).multiply(BigInteger.valueOf(18))); assertEquals(new Rational("15/2"), new Rational(5).multiply(1.5)); assertEquals(new Rational("627989997/125000000"), new Rational(5).multiply(new BigDecimal("1.00478399520"))); assertEquals(new Rational("180/37"), new Rational("24/37").multiply(new Rational(15, 2))); } @Test public void testSubtractOperator() { assertEquals(Rational.ONE.negate(), new Rational(5).subtract(6)); assertEquals(new Rational(-7), new Rational(5).subtract(12L)); assertEquals(new Rational(-13), new Rational(5).subtract(BigInteger.valueOf(18))); assertEquals(new Rational("7/2"), new Rational(5).subtract(1.5)); assertEquals(new Rational("2497010003/625000000"), new Rational(5).subtract(new BigDecimal("1.00478399520"))); assertEquals(new Rational("-507/74"), new Rational("24/37").subtract(new Rational(15, 2))); } @Test public void testAddOperator() { assertEquals(new Rational(11), new Rational(5).add(6)); assertEquals(new Rational(17), new Rational(5).add(12L)); assertEquals(new Rational(23), new Rational(5).add(BigInteger.valueOf(18))); assertEquals(new Rational("13/2"), new Rational(5).add(1.5)); assertEquals(new Rational("3752989997/625000000"), new Rational(5).add(new BigDecimal("1.00478399520"))); assertEquals(new Rational("603/74"), new Rational("24/37").add(new Rational(15, 2))); } @Test public void testDivideOperator() { assertEquals(new Rational(5, 6), new Rational(5).divide(6)); assertEquals(new Rational("5 / 12"), new Rational(5).divide(12L)); assertEquals(new Rational("5/18"), new Rational(5).divide(BigInteger.valueOf(18))); assertEquals(new Rational("10/3"), new Rational(5).divide(1.5)); assertEquals(new Rational("3125000000/627989997"), new Rational(5).divide(new BigDecimal("1.00478399520"))); assertEquals(new Rational("16/185"), new Rational("24/37").divide(new Rational(15, 2))); } @Test public void testReciprocalOperator() { assertEquals(new Rational("1/5"), new Rational(5).reciprocal()); assertEquals(new Rational("1/50"), new Rational(50L).reciprocal()); assertEquals(new Rational("1/238903247898923"), new Rational(new BigInteger("238903247898923")).reciprocal()); assertEquals(new Rational("2/13"), new Rational("13/2").reciprocal()); assertEquals(new Rational("625000000/3752989997"), new Rational("3752989997/625000000").reciprocal()); assertEquals(new Rational(37, 24), new Rational(24, 37).reciprocal()); assertEquals(Rational.ZERO, Rational.ZERO.reciprocal()); } @Test public void testNegateOperator() { assertEquals(new Rational("-5"), new Rational(5).negate()); assertEquals(new Rational("-4/5"), new Rational("32/40").negate()); assertEquals(Rational.ZERO, Rational.ZERO.negate()); } @Test public void testAbsOperator() { assertEquals(new Rational("5"), new Rational(5).abs()); assertEquals(new Rational("5"), new Rational(-5).abs()); assertEquals(new Rational("32/40"), new Rational("32/-40").negate()); assertEquals(Rational.ZERO, Rational.ZERO.abs()); } @Test public void testPowOperator() { assertEquals(Rational.ONE, new Rational(5).pow(0)); assertEquals(new Rational("-5"), new Rational(-5).pow(1)); assertEquals(new Rational("-1073741824/30517578125"), new Rational("32/-40").pow(15)); assertEquals(new Rational("268435456/6103515625"), new Rational("32/-40").pow(14)); assertEquals(new Rational("1/9765625"), new Rational(-5).pow(-10)); assertEquals(Rational.ZERO, Rational.ZERO.pow(4)); } @Test public void testSignum() { assertEquals(1, new Rational(5).signum()); assertEquals(-1, new Rational(-15).signum()); assertEquals(0, new Rational(null, BigInteger.valueOf(3)).signum()); assertEquals(0, Rational.ZERO.signum()); assertEquals(-1, new Rational("32/-40").pow(15).signum()); assertEquals(1, new Rational("32/-40").pow(14).signum()); } @Test public void testIsInteger() { assertTrue(new Rational(5).isInteger()); assertTrue(new Rational(0).isInteger()); assertTrue(new Rational(-5).isInteger()); assertFalse(new Rational(5.5).isInteger()); assertFalse(new Rational(5, 2).isInteger()); } @Test public void testGetters() { Rational rational = new Rational(22, 6); assertEquals(22, rational.getNumerator().intValue()); assertEquals(6, rational.getDenominator().intValue()); assertEquals(11, rational.getReducedNumerator().intValue()); assertEquals(3, rational.getReducedDenominator().intValue()); assertEquals(2, rational.getGreatestCommonDivisor().intValue()); } @Test public void testStringOutputs() { Rational rational = new Rational(22, 6); assertEquals("22/6", rational.toString()); assertEquals("11/3", rational.toReducedString()); assertEquals("3.66666666666666666667", rational.toDecimalString()); assertEquals("16/6", rational.toHexString()); assertEquals("b/3", rational.toReducedHexString()); assertEquals("Value: 22/6, Reduced: 11/3, Decimal: 3.66666666666666666667", rational.toDebugString()); } @Test public void testNumberInterface() { Rational rational = new Rational(22, 6); assertEquals(3, rational.intValue()); assertEquals(3L, rational.longValue()); assertEquals(-3L, rational.negate().longValue()); assertEquals(BigInteger.valueOf(3), rational.bigIntegerValue()); assertEquals(3.666667f, rational.floatValue(), 0.0f); assertEquals(3.666666666666667, rational.doubleValue(), 0.0); assertEquals( new BigDecimal("3.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667"), rational.bigDecimalValue() ); assertEquals( new BigDecimal("3.6666666666666666666"), rational.bigDecimalValue(new MathContext(20, RoundingMode.FLOOR)) ); assertEquals( new BigDecimal("3.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"), rational.bigDecimalValue(RoundingMode.FLOOR) ); assertEquals( new BigDecimal("3.66666666666666666666666666666666666666666666666667"), rational.bigDecimalValue(50, RoundingMode.CEILING) ); exception.expect(ArithmeticException.class); exception.expectMessage("Non-terminating decimal expansion; no exact representable decimal result."); assertEquals( new BigDecimal("3.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667"), rational.bigDecimalValue(MathContext.UNLIMITED) ); } @Test public void testComparison() { assertEquals(0, new Rational(22, 6).compareTo(new Rational(11, 3))); assertEquals(1, new Rational(22, 6).compareTo(new Rational(11, 4))); assertEquals(-1, new Rational(22, 6).compareTo(new Rational(12, 3))); assertEquals(1, new Rational(22, 6).compareTo((byte) 3)); assertEquals(-1, new Rational(22, 6).compareTo((byte) 4)); assertEquals(1, new Rational(22, 6).compareTo((short) 3)); assertEquals(-1, new Rational(22, 6).compareTo((short) 4)); assertEquals(1, new Rational(22, 6).compareTo(3)); assertEquals(-1, new Rational(22, 6).compareTo(4)); assertEquals(0, new Rational(24, 6).compareTo(4)); assertEquals(1, new Rational(22, 6).compareTo(3L)); assertEquals(-1, new Rational(22, 6).compareTo(4L)); assertEquals(1, new Rational(22, 6).compareTo(3f)); assertEquals(1, new Rational(22, 6).compareTo(3.6f)); assertEquals(-1, new Rational(22, 6).compareTo(3.7f)); assertEquals(1, new Rational(22, 6).compareTo(3.666666f)); assertEquals(-1, new Rational(22, 6).compareTo(3.666667f)); assertEquals(1, new Rational(22, 6).compareTo(3.666666666666666)); assertEquals(-1, new Rational(22, 6).compareTo(3.666666666666667)); assertEquals(1, new Rational(22, 6).compareTo(new BigDecimal("3.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666"))); assertEquals(-1, new Rational(22, 6).compareTo(new BigDecimal("3.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667"))); assertTrue(new Rational(22, 6).equalsExact(new Rational(22, 6))); assertFalse(new Rational(22, 6).equalsExact(new Rational(11, 3))); } @Test public void testGetMultipliers() { Rational a = new Rational(22, 6); Rational b = new Rational(-5, 34); BigInteger[] array = a.getMultipliers(b); assertArrayEquals(new BigInteger[] {BigInteger.valueOf(34), BigInteger.valueOf(3)}, array); assertEquals(a.reducedDenominator.multiply(array[0]), b.reducedDenominator.multiply(array[1])); a = new Rational(4.235); b = new Rational(78, -14); array = a.getMultipliers(b); assertArrayEquals(new BigInteger[] {BigInteger.valueOf(7), BigInteger.valueOf(200)}, array); assertEquals(a.reducedDenominator.multiply(array[0]), b.reducedDenominator.multiply(array[1])); } @Test public void testCalculateGreatestCommonDivisor() { assertEquals(5L, Rational.calculateGreatestCommonDivisor(40, 5)); assertEquals(1L, Rational.calculateGreatestCommonDivisor(40, 7)); assertEquals(2L, Rational.calculateGreatestCommonDivisor(-54, 128)); } @Test public void testCalculateLeastCommonMultiple() { assertEquals(BigInteger.valueOf(40), Rational.calculateLeastCommonMultiple(BigInteger.valueOf(40), BigInteger.valueOf(5))); assertEquals(BigInteger.valueOf(65610), Rational.calculateLeastCommonMultiple(BigInteger.valueOf(270), BigInteger.valueOf(6561))); assertEquals(BigInteger.valueOf(315), Rational.calculateLeastCommonMultiple(BigInteger.valueOf(63), BigInteger.valueOf(35))); } }