0

Am trying to round up 2 decimal places using a method I wrote in my class.

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mathutils</groupId>
    <artifactId>mathutils</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>5.1.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.20.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.0</version>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

MathUtils.java:

public class MathUtils {
    
    public static double roundUp(double value) {
        DecimalFormat df = new DecimalFormat("#.##");
        return(Double.valueOf(df.format(value)));
    }

}

MathUtilsTest.java:

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class MathUtilsTest {

    @Test
    public void roundUp() {
        assertThat(MathUtils.roundUp(0.565)).isEqualTo(0.57);  // this needs to be 57 but actual was .56
        assertThat(MathUtils.roundUp(0.5649)).isEqualTo(0.56); // works
    }

}    

Question(s):

  • Need 0.0565 to round up to 0.57 but fails with this:
org.opentest4j.AssertionFailedError: 
expected: 0.57
 but was: 0.56
Expected :0.57
Actual   :0.56
PacificNW_Lover
  • 4,746
  • 31
  • 90
  • 144
  • See the dupe on how the default rounding works and you should use instead. – Tom Jul 18 '21 at 01:40
  • This is not so much a coding problem since at root is the issue of the imprecision and volatility of floating point numbers on hardware. Because of this problem, classes like `BigDecimal` were invented. You could make your assertions based on that class, but comparing `double` or `float` for *|exact* equality shouldn't be done. – g00se Jul 18 '21 at 10:28
  • @Tom - After looking at the dupe, I tried ```roundingMode = RoundingMode.UP``` and whereas that worked for the first assert, it broke the second assert that was working originally... – PacificNW_Lover Jul 18 '21 at 22:45
  • @g00se - Thanks for the insight! Can you give me an example using BigDecimal? – PacificNW_Lover Jul 18 '21 at 22:48
  • You should take a look here https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html. `RoundingMode.UP` is always rounding up, you should work with `RoundingMode.HALF_UP` instead. Regarding your test cases, you also need to factor in the imprecision of float and double. Your `0.565` is actually `0.564999999999999946709294817992486059665679931640625`, thus rounded down when using that literal value. When you need exact values, then use `BigDecimal` instead. – Tom Jul 18 '21 at 23:19
  • @Tom - ```RoundingMode.HALF_UP``` fixed the issue with the second assertion, but not with the first assertion, it fails with 0.565 turning into 0.56 instead of 0.57. Is there a different way to achieve this precision? Code samples would be greatly appreicated. – PacificNW_Lover Jul 19 '21 at 06:38
  • Got it working but am wondering how come I can't answer my own question on this thread? Usually, Stack Overflow allows you to answer your own question? This comments section would truncate my solution... – PacificNW_Lover Jul 20 '21 at 07:50

0 Answers0