/* * Copyright (C) 2009-2012 University of Freiburg * * This file is part of SMTInterpol. * * SMTInterpol is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SMTInterpol 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SMTInterpol. If not, see <http://www.gnu.org/licenses/>. */ package de.uni_freiburg.informatik.ultimate.logic; import java.math.BigInteger; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Test Class for Rationals. * * @author Jochen Hoenicke */ @RunWith(JUnit4.class) public final class RationalTest { final static BigInteger LARGE = new BigInteger("1234567890123456789012345678901234567890"); final static Rational LARGE_RAT = Rational.valueOf(LARGE, BigInteger.ONE); static final Rational SMALL_RAT = Rational.valueOf(BigInteger.ONE, LARGE.divide(BigInteger.valueOf(7)));// NOCHECKSTYLE static final Rational RAT = LARGE_RAT.mul(SMALL_RAT); static final Rational MEDIUM1 = Rational.valueOf(Integer.MAX_VALUE, 1); static final Rational MEDIUM2 = Rational.valueOf(1, Integer.MAX_VALUE); static Rational MEDIUM3 = Rational.valueOf(0x789abcdf, 0x76543210);// NOCHECKSTYLE static final Rational SPECIAL1 = Rational.valueOf( BigInteger.ONE, BigInteger.valueOf(Integer.MIN_VALUE)); static final Rational SPECIAL2 = Rational.valueOf( BigInteger.valueOf(Integer.MIN_VALUE), BigInteger.ONE); static final Rational[] RATIONALS = { Rational.ONE, Rational.MONE, Rational.ZERO, Rational.NAN, Rational.POSITIVE_INFINITY, Rational.NEGATIVE_INFINITY, LARGE_RAT, SMALL_RAT, RAT, MEDIUM1, MEDIUM2, MEDIUM3, SPECIAL1, SPECIAL2, LARGE_RAT.negate(), SMALL_RAT.negate(), RAT.negate(), MEDIUM1.negate(), MEDIUM2.negate(), MEDIUM3.negate(), SPECIAL1.negate(), SPECIAL2.negate() }; @Test public void testGCD() { Assert.assertEquals(0, Rational.gcd(0, 0)); Assert.assertEquals(5, Rational.gcd(5, 0));// NOCHECKSTYLE Assert.assertEquals(5, Rational.gcd(0, 5));// NOCHECKSTYLE Assert.assertEquals(1, Rational.gcd(1, 5));// NOCHECKSTYLE Assert.assertEquals(1, Rational.gcd(5, 1));// NOCHECKSTYLE Assert.assertEquals(37, Rational.gcd(111, 37));// NOCHECKSTYLE Assert.assertEquals(10, Rational.gcd(150, 220));// NOCHECKSTYLE Assert.assertEquals(Integer.MAX_VALUE, Rational.gcd(Integer.MAX_VALUE, Integer.MAX_VALUE)); Assert.assertEquals(1, Rational.gcd(Integer.MAX_VALUE, 720720));// NOCHECKSTYLE Assert.assertEquals(77, Rational.gcd(1309, 720720));// NOCHECKSTYLE } @Test public void testGCDlong() { Assert.assertEquals(0, Rational.gcd(0L, 0L)); Assert.assertEquals(5, Rational.gcd(5L, 0L));// NOCHECKSTYLE Assert.assertEquals(5, Rational.gcd(0L, 5L));// NOCHECKSTYLE Assert.assertEquals(1, Rational.gcd(1L, 5L));// NOCHECKSTYLE Assert.assertEquals(1, Rational.gcd(5L, 1L));// NOCHECKSTYLE Assert.assertEquals(37, Rational.gcd(111L, 37L));// NOCHECKSTYLE Assert.assertEquals(10, Rational.gcd(150L, 220L));// NOCHECKSTYLE Assert.assertEquals(Long.MAX_VALUE, Rational.gcd(Long.MAX_VALUE, Long.MAX_VALUE)); Assert.assertEquals(7, Rational.gcd(Long.MAX_VALUE, 720720L));// NOCHECKSTYLE Assert.assertEquals(1, Rational.gcd(Long.MAX_VALUE, Long.MAX_VALUE >> 1)); Assert.assertEquals(77, Rational.gcd(1309l, 720720L));// NOCHECKSTYLE } @Test public void testValueOf() { Assert.assertSame(Rational.ZERO, Rational.valueOf(0, 5));// NOCHECKSTYLE Assert.assertSame(Rational.ONE, Rational.valueOf(5, 5));// NOCHECKSTYLE Assert.assertSame(Rational.MONE, Rational.valueOf(-5, 5));// NOCHECKSTYLE Assert.assertSame(Rational.ZERO, Rational.valueOf(0, Long.MAX_VALUE)); Assert.assertSame(Rational.ONE, Rational.valueOf(Long.MAX_VALUE, Long.MAX_VALUE)); Assert.assertSame(Rational.MONE, Rational.valueOf(-Long.MAX_VALUE, Long.MAX_VALUE)); Assert.assertSame(Rational.POSITIVE_INFINITY, Rational.valueOf(Long.MAX_VALUE, 0)); Assert.assertSame(Rational.NEGATIVE_INFINITY, Rational.valueOf(-Long.MAX_VALUE, 0)); Assert.assertSame(Rational.NAN, Rational.valueOf(0, 0)); Assert.assertEquals(Rational.valueOf(2, 1), Rational.valueOf(0x7fffffe, 0x3ffffffl));// NOCHECKSTYLE Assert.assertTrue(Rational.valueOf(1, -Long.MAX_VALUE).isNegative()); Assert.assertTrue(!Rational.valueOf(1, Long.MAX_VALUE).isNegative()); final BigInteger large = new BigInteger( "1234567890123456789012345678901234567890"); Assert.assertSame(Rational.ZERO, Rational.valueOf( BigInteger.ZERO, BigInteger.ONE)); Assert.assertSame(Rational.ZERO, Rational.valueOf(BigInteger.ZERO, large)); Assert.assertSame(Rational.ONE, Rational.valueOf(large, large)); Assert.assertSame(Rational.ONE, Rational.valueOf( large.negate(), large.negate())); Assert.assertSame(Rational.MONE, Rational.valueOf(large, large.negate())); Assert.assertSame(Rational.MONE, Rational.valueOf(large.negate(), large)); Assert.assertSame(Rational.POSITIVE_INFINITY, Rational.valueOf( large, BigInteger.ZERO)); Assert.assertSame(Rational.NEGATIVE_INFINITY, Rational.valueOf( large.negate(), BigInteger.ZERO)); Assert.assertSame(Rational.NAN, Rational.valueOf( BigInteger.ZERO, BigInteger.ZERO)); } @Test public void testAdd() { for (int i = 0; i < RATIONALS.length; i++) { for (int j = i + 1; j < RATIONALS.length; j++) { Assert.assertFalse(RATIONALS[i].equals(RATIONALS[j])); Assert.assertFalse(RATIONALS[j].equals(RATIONALS[i])); } } for (int i = 0; i < RATIONALS.length; i++) { Assert.assertSame("NAN + " + RATIONALS[i], Rational.NAN, Rational.NAN.add(RATIONALS[i])); Assert.assertSame(RATIONALS[i] + " + NAN", Rational.NAN, RATIONALS[i].add(Rational.NAN)); if (RATIONALS[i] != Rational.NAN) { Rational expect = RATIONALS[i] == Rational.NEGATIVE_INFINITY ? Rational.NAN : Rational.POSITIVE_INFINITY; Assert.assertSame(expect, RATIONALS[i].add(Rational.POSITIVE_INFINITY)); Assert.assertSame(expect, Rational.POSITIVE_INFINITY.add(RATIONALS[i])); expect = RATIONALS[i] == Rational.POSITIVE_INFINITY ? Rational.NAN : Rational.NEGATIVE_INFINITY; Assert.assertSame(expect, RATIONALS[i].add(Rational.NEGATIVE_INFINITY)); Assert.assertSame(expect, Rational.NEGATIVE_INFINITY.add(RATIONALS[i])); } } for (int i = 0; i < RATIONALS.length; i++) { for (int j = i + 1; j < RATIONALS.length; j++) { Assert.assertEquals(RATIONALS[i].add(RATIONALS[j]), RATIONALS[j].add(RATIONALS[i])); } } } @Test public void testMul() { Assert.assertEquals(Rational.ZERO, Rational.POSITIVE_INFINITY.inverse()); Assert.assertEquals(Rational.ZERO, Rational.NEGATIVE_INFINITY.inverse()); Assert.assertEquals(Rational.POSITIVE_INFINITY, Rational.ZERO.inverse()); Assert.assertEquals(Rational.NAN, Rational.ZERO.mul(Rational.POSITIVE_INFINITY)); Assert.assertEquals(Rational.NAN, Rational.ZERO.mul(Rational.NEGATIVE_INFINITY)); for (int i = 0; i < RATIONALS.length; i++) { if (RATIONALS[i] != Rational.ZERO && !RATIONALS[i].denominator().equals(BigInteger.ZERO)) { Assert.assertEquals(Rational.ONE, RATIONALS[i].mul(RATIONALS[i].inverse())); } for (int j = i + 1; j < RATIONALS.length; j++) { Assert.assertEquals(RATIONALS[i].mul(RATIONALS[j]), RATIONALS[j].mul(RATIONALS[i])); Assert.assertEquals(RATIONALS[i].mul(RATIONALS[j]).signum(), RATIONALS[i].signum() * RATIONALS[j].signum()); } } } @Test public void testDiverse() { for (int i = 0; i < RATIONALS.length; i++) { Assert.assertEquals(0, RATIONALS[i].compareTo(RATIONALS[i])); for (int j = i + 1; j < RATIONALS.length; j++) { if (RATIONALS[i] != Rational.NAN && RATIONALS[j] != Rational.NAN) { Assert.assertTrue(RATIONALS[i] + " =<>= " + RATIONALS[j], RATIONALS[i].compareTo(RATIONALS[j]) != 0); } Assert.assertEquals(RATIONALS[i] + " <=> " + RATIONALS[j], RATIONALS[i].compareTo(RATIONALS[j]), -RATIONALS[j].compareTo(RATIONALS[i])); } } for (int i = 0; i < RATIONALS.length; i++) { Assert.assertEquals(RATIONALS[i].isNegative(), RATIONALS[i].compareTo(Rational.ZERO) < 0); Assert.assertEquals(RATIONALS[i].signum(), RATIONALS[i].compareTo(Rational.ZERO)); if (RATIONALS[i] != Rational.NEGATIVE_INFINITY) { Assert.assertEquals(RATIONALS[i], RATIONALS[i].inverse().inverse()); } Assert.assertEquals(RATIONALS[i], RATIONALS[i].negate().negate()); Assert.assertEquals(RATIONALS[i], RATIONALS[i].floor().add(RATIONALS[i].frac())); Assert.assertEquals(RATIONALS[i], RATIONALS[i].frac().add(RATIONALS[i].floor())); Assert.assertFalse(RATIONALS[i].frac().isNegative()); Assert.assertTrue(RATIONALS[i].frac().compareTo(Rational.ONE) < 0); Assert.assertEquals(RATIONALS[i].isIntegral(), RATIONALS[i].frac() == Rational.ZERO); } } @Test public void testDiv() { Assert.assertSame(Rational.POSITIVE_INFINITY, SMALL_RAT.div(Rational.ZERO)); Assert.assertSame(Rational.NEGATIVE_INFINITY, SMALL_RAT.negate().div(Rational.ZERO)); Assert.assertSame(Rational.POSITIVE_INFINITY, LARGE_RAT.div(Rational.ZERO)); Assert.assertSame(Rational.NEGATIVE_INFINITY, LARGE_RAT.negate().div(Rational.ZERO)); Assert.assertSame(Rational.POSITIVE_INFINITY, Rational.POSITIVE_INFINITY.div(Rational.ZERO)); Assert.assertSame(Rational.NEGATIVE_INFINITY, Rational.NEGATIVE_INFINITY.div(Rational.ZERO)); Assert.assertSame(Rational.NAN, Rational.NAN.div(Rational.ZERO)); Assert.assertSame(Rational.NAN, Rational.POSITIVE_INFINITY.div(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.POSITIVE_INFINITY.div(Rational.NEGATIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.NEGATIVE_INFINITY.div(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.NEGATIVE_INFINITY.div(Rational.NEGATIVE_INFINITY)); Assert.assertSame(Rational.ZERO, Rational.ONE.div(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.ZERO, Rational.ONE.div(Rational.NEGATIVE_INFINITY)); Assert.assertSame(Rational.ZERO, LARGE_RAT.div(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.ZERO, LARGE_RAT.div(Rational.NEGATIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.POSITIVE_INFINITY.add(Rational.NEGATIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.NEGATIVE_INFINITY.add(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.POSITIVE_INFINITY.sub(Rational.POSITIVE_INFINITY)); Assert.assertSame(Rational.NAN, Rational.NEGATIVE_INFINITY.sub(Rational.NEGATIVE_INFINITY)); } }