/**
* Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite 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.0 of the License, or
* (at your option) any later version.
*
* EvoSuite 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 Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/
package org.evosuite.instrumentation.testability;
import static org.junit.Assert.*;
import org.evosuite.testcase.DefaultTestCase;
import org.evosuite.testcase.TestCase;
import org.evosuite.testcase.statements.numeric.DoublePrimitiveStatement;
import org.junit.Test;
public class TestDoubleFloatComparison {
@Test
public void testDoubleComparison() {
int x = BooleanHelper.doubleSubG(0.0, 0.0);
int y = BooleanHelper.doubleSubG(10.0, 0.0);
assertTrue(y > x);
int z = BooleanHelper.doubleSubG(20.0, 0.0);
assertTrue(z > x);
assertTrue(z > y);
}
@Test
public void testDoubleComparison2() {
assertEquals(Double.compare(1000.0, 1.0) > 0, BooleanHelper.doubleSubG(1000.0, 1.0) > 0);
assertEquals(Double.compare(1000.0, 1.0) < 0, BooleanHelper.doubleSubG(1000.0, 1.0) < 0);
assertEquals(Double.compare(1000.0, 1.0) == 0, BooleanHelper.doubleSubG(1000.0, 1.0) == 0);
assertEquals(Double.compare(1.0, 1000.0) > 0, BooleanHelper.doubleSubG(1.0, 1000.0) > 0);
assertEquals(Double.compare(1.0, 1000.0) < 0, BooleanHelper.doubleSubG(1.0, 1000.0) < 0);
assertEquals(Double.compare(1.0, 1000.0) == 0, BooleanHelper.doubleSubG(1.0, 1000.0) == 0);
}
@Test
public void testDoubleNegativeComparison() {
int x = BooleanHelper.doubleSubG(0.0, 0.0);
int y = BooleanHelper.doubleSubG(-10.0, 0.0);
assertTrue(x > y);
int z = BooleanHelper.doubleSubG(-20.0, 0.0);
assertTrue(z < x);
assertTrue(z < y);
}
@Test
public void testLargeDoubleComparison() {
int x = BooleanHelper.doubleSubG(29380.0, 3266.3);
int y = BooleanHelper.doubleSubG(23562985.124125, 2938.2525);
assertTrue(y > x);
int z = BooleanHelper.doubleSubG(238628629.23423, 2352.2323);
assertTrue(z > x);
assertTrue(z > y);
}
@Test
public void testLargeDoubleNegativeComparison() {
int x = BooleanHelper.doubleSubG(-29380.0, 3266.3);
int y = BooleanHelper.doubleSubG(-23562985.124125, 2938.2525);
assertTrue(y < x);
int z = BooleanHelper.doubleSubG(-238628629.23423, 2352.2323);
assertTrue(z < x);
assertTrue(z < y);
}
@Test
public void testExamples() {
double x1 = -1939.9207985389992;
double x2 = -1941.2134374492741;
double y1 = -89.0;
double y2 = -95.11816569743506;
double z1 = 291.0;
double z2 = 291.35140748465363;
int a1 = BooleanHelper.doubleSubG(x1, 0.0);
int a2 = BooleanHelper.doubleSubG(x2, 0.0);
assertTrue(a1 > a2);
int b1 = BooleanHelper.doubleSubG(y1, 0.0);
int b2 = BooleanHelper.doubleSubG(y2, 0.0);
assertTrue(b1 > b2);
int c1 = BooleanHelper.doubleSubG(z1, 0.0);
int c2 = BooleanHelper.doubleSubG(z2, 0.0);
assertTrue(c1 < c2);
}
@Test
public void testDelta() {
TestCase test = new DefaultTestCase();
DoublePrimitiveStatement statement1 = new DoublePrimitiveStatement(test);
DoublePrimitiveStatement statement2 = new DoublePrimitiveStatement(test);
double d1 = statement1.getValue();
double d2 = statement2.getValue();
int val = BooleanHelper.doubleSubG(d1, d2);
assertEquals(val > 0, d1 > d2);
assertEquals(val < 0, d1 < d2);
assertEquals(val == 0, d1 == d2);
for(int i = 0; i < 100; i++) {
statement1.delta();
statement2.delta();
d1 = statement1.getValue();
d2 = statement2.getValue();
val = BooleanHelper.doubleSubG(d1, d2);
assertEquals(val > 0, d1 > d2);
assertEquals(val < 0, d1 < d2);
assertEquals(val == 0, d1 == d2);
}
for(int i = 0; i < 100; i++) {
statement1.randomize();
statement2.randomize();
d1 = statement1.getValue();
d2 = statement2.getValue();
val = BooleanHelper.doubleSubG(d1, d2);
assertEquals(val > 0, d1 > d2);
assertEquals(val < 0, d1 < d2);
assertEquals(val == 0, d1 == d2);
}
}
@Test
public void testInfinityAndDouble() {
assertTrue(BooleanHelper.doubleSubG(Double.POSITIVE_INFINITY, 0.0) != 0);
assertTrue(BooleanHelper.doubleSubG(Double.NEGATIVE_INFINITY, 0.0) != 0);
assertTrue(BooleanHelper.doubleSubG(0.0, Double.POSITIVE_INFINITY) != 0);
assertTrue(BooleanHelper.doubleSubG(0.0, Double.NEGATIVE_INFINITY) != 0);
}
@Test
public void testNaNAndDouble() {
assertEquals(1, BooleanHelper.doubleSubG(Float.NaN, 0.0));
assertEquals(1, BooleanHelper.doubleSubG(0.0, Double.NaN));
assertEquals(-1, BooleanHelper.doubleSubL(Float.NaN, 0.0));
assertEquals(-1, BooleanHelper.doubleSubL(0.0, Double.NaN));
}
// TODO: Double.compare has different semantics wrt NaN, does this test really make sense?
@Test
public void testDoubleNaN2() {
double p = Double.NaN;
assertEquals(Double.compare(p, Double.NaN) > 0, BooleanHelper.doubleSubL(p, Double.NaN) > 0);
assertEquals(Double.compare(p, Double.NaN) > 0, BooleanHelper.doubleSubG(p, Double.NaN) < 0);
// compare is different to dcmpl/g
// assertEquals(Double.compare(p, Double.NaN) == 0, BooleanHelper.doubleSubG(p, Double.NaN) == 0);
assertEquals(Double.compare(p, Double.NaN) < 0, BooleanHelper.doubleSubL(p, Double.NaN) > 0);
assertEquals(Double.compare(p, Double.NaN) < 0, BooleanHelper.doubleSubG(p, Double.NaN) < 0);
assertEquals(Double.compare(p, 0.0) < 0, BooleanHelper.doubleSubG(p, 0.0) < 0);
assertEquals(Double.compare(p, 0.0) == 0, BooleanHelper.doubleSubG(p, 0.0) == 0);
assertEquals(Double.compare(p, 0.0) > 0, BooleanHelper.doubleSubG(p, 0.0) > 0);
assertEquals(Double.compare(p, 1.0) > 0 , BooleanHelper.doubleSubG(p, 1.0) > 0);
assertEquals(Double.compare(p, 1.0) == 0 , BooleanHelper.doubleSubG(p, 1.0) == 0);
assertEquals(Double.compare(p, 1.0) < 0 , BooleanHelper.doubleSubG(p, 1.0) < 0);
assertTrue(BooleanHelper.doubleSubG(0.0, p) > 0);
assertEquals(Double.compare(0.0, p) < 0, BooleanHelper.doubleSubG(0.0, p) > 0);
//assertEquals(Double.compare(0.0, p) == 0, BooleanHelper.doubleSubG(0.0, p) == 0);
assertEquals(Double.compare(0.0, p) > 0, BooleanHelper.doubleSubG(0.0, p) < 0);
assertEquals(Double.compare(1.0, p) < 0 , BooleanHelper.doubleSubG(1.0, p) > 0);
//assertEquals(Double.compare(1.0, p) == 0 , BooleanHelper.doubleSubG(1.0, p) == 0);
assertEquals(Double.compare(1.0, p) < 0 , BooleanHelper.doubleSubL(1.0, p) < 0);
}
// TODO: Float.compare has different semantics wrt NaN, does this test really make sense?
@Test
public void testFloatNaN2() {
float p = Float.NaN;
assertEquals(Float.compare(p, Float.NaN) > 0, BooleanHelper.floatSubL(p, Float.NaN) > 0);
assertEquals(Float.compare(p, Float.NaN) > 0, BooleanHelper.floatSubG(p, Float.NaN) < 0);
// compare behaves different than fcmpl/fcmpg
//assertEquals(Float.compare(p, Float.NaN) == 0, BooleanHelper.floatSubG(p, Float.NaN) == 0);
assertEquals(Float.compare(p, Float.NaN) < 0, BooleanHelper.floatSubL(p, Float.NaN) > 0);
assertEquals(Float.compare(p, Float.NaN) < 0, BooleanHelper.floatSubG(p, Float.NaN) < 0);
assertEquals(Float.compare(p, 0.0f) < 0, BooleanHelper.floatSubG(p, 0.0f) < 0);
assertEquals(Float.compare(p, 0.0f) == 0, BooleanHelper.floatSubG(p, 0.0f) == 0);
assertEquals(Float.compare(p, 0.0f) > 0, BooleanHelper.floatSubG(p, 0.0f) > 0);
assertEquals(Float.compare(p, 1.0f) > 0 , BooleanHelper.floatSubG(p, 1.0f) > 0);
assertEquals(Float.compare(p, 1.0f) == 0 , BooleanHelper.floatSubG(p, 1.0f) == 0);
assertEquals(Float.compare(p, 1.0f) < 0 , BooleanHelper.floatSubG(p, 1.0f) < 0);
}
@Test
public void testInfinityAndFloat() {
assertTrue(BooleanHelper.floatSubG(Float.POSITIVE_INFINITY, 0.0F) != 0);
assertTrue(BooleanHelper.floatSubG(Float.NEGATIVE_INFINITY, 0.0F) != 0);
assertTrue(BooleanHelper.floatSubG(0.0F, Float.POSITIVE_INFINITY) != 0);
assertTrue(BooleanHelper.floatSubG(0.0F, Float.NEGATIVE_INFINITY) != 0);
}
@Test
public void testNaNAndFloat() {
assertEquals(1, BooleanHelper.floatSubG(Float.NaN, 0.0F));
assertEquals(1, BooleanHelper.floatSubG(0.0F, Float.NaN));
assertEquals(-1, BooleanHelper.floatSubL(Float.NaN, 0.0F));
assertEquals(-1, BooleanHelper.floatSubL(0.0F, Float.NaN));
}
@Test
public void testRoundingErrorForSmallNumber() {
float a = -1.4E-45F;
assertTrue(BooleanHelper.floatSubG(a, 0.0f) < 0);
}
}