/* (c) 2016 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wfs.json; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Random; import org.junit.Test; /** * * Test rounding * * @author Dean Povey * */ public class RoundingUtilTest { @Test public void testSpecialCases() { for (int numDecimals = 0; numDecimals < 17; numDecimals++) { assertThat(Double.isNaN(RoundingUtil.round(Double.NaN, numDecimals)), is(true)); assertThat(RoundingUtil.round(Double.NEGATIVE_INFINITY, numDecimals), is(equalTo(Double.NEGATIVE_INFINITY))); assertThat(RoundingUtil.round(Double.POSITIVE_INFINITY, numDecimals), is(equalTo(Double.POSITIVE_INFINITY))); } } @Test public void testSpecificCases() { assertThat(RoundingUtil.round(0d, 0), is(equalTo(0d))); assertThat(RoundingUtil.round(0.1, 0), is(equalTo(0d))); assertThat(RoundingUtil.round(0.1, 1), is(equalTo(0.1))); assertThat(RoundingUtil.round(0.1, 2), is(equalTo(0.1))); assertThat(RoundingUtil.round(0.05, 1), is(equalTo(0.1))); assertThat(RoundingUtil.round(-0.05, 1), is(equalTo(0d))); assertThat(RoundingUtil.round(0.0000001, 5), is(equalTo(0d))); assertThat(RoundingUtil.round(1.0000001, 7), is(equalTo(1.0000001))); assertThat(RoundingUtil.round(1.00000015, 7), is(equalTo(1.0000002))); assertThat(RoundingUtil.round(1E-3, 7), is(equalTo(0.001))); assertThat(RoundingUtil.round(1E-4, 3), is(equalTo(0d))); assertThat(RoundingUtil.round(1E-10, 10), is(equalTo(1E-10))); } @Test public void testNoRoundingWhenPrecisionWouldBeExceeded() { // Test cases where precision is exceeded. assertThat(RoundingUtil.round(1.01234567890123456E12, 1), is(equalTo(1.0123456789012E12))); assertThat(RoundingUtil.round(1.01234567890123456E12, 2), is(equalTo(1.01234567890123E12))); assertThat(RoundingUtil.round(1.01234567890123456E13, 1), is(equalTo(1.01234567890123E13))); assertThat(RoundingUtil.round(1.01234567890123456E13, 2), is(equalTo(1.012345678901235E13))); assertThat(RoundingUtil.round(1.01234567890123456E14, 1), is(equalTo(1.012345678901235E14))); assertThat(RoundingUtil.round(1.01234567890123456E14, 2), is(equalTo(1.0123456789012346E14))); assertThat(RoundingUtil.round(1.01234567890123456E15, 1), is(equalTo(1.0123456789012345E15))); assertThat(RoundingUtil.round(1.01234567890123456E15, 2), is(equalTo(1.0123456789012345E15))); assertThat(RoundingUtil.round(1.01234567890123456E16, 1), is(equalTo(1.0123456789012346E16))); assertThat(RoundingUtil.round(1.01234567890123456E16, 2), is(equalTo(1.0123456789012346E16))); assertThat(RoundingUtil.round(1.0123456789012345E17, 1), is(equalTo(1.0123456789012345E17))); assertThat(RoundingUtil.round(1.0123456789012345E18, 1), is(equalTo(1.0123456789012345E18))); assertThat(RoundingUtil.round(1.01234567890123451E19, 1), is(equalTo(1.0123456789012345E19))); assertThat(RoundingUtil.round(Double.MIN_VALUE, 15), is(equalTo(0d))); assertThat(RoundingUtil.round(Double.MAX_VALUE, 1), is(equalTo(Double.MAX_VALUE))); } @Test public void testRandomRoundingVsBigDecimal() { Random r = new Random(); for (int i = 0; i < 10000; i++) { double value = r.nextDouble(); for (int numDecimals = 0; numDecimals <= 8; numDecimals++) { double expected = new BigDecimal(Double.toString(value)).setScale(numDecimals, RoundingMode.HALF_UP).doubleValue(); double actual = RoundingUtil.round(value, numDecimals); assertThat(actual, is(equalTo(expected))); } } } }