BigDecimal and “java.lang.ArithmeticException: Non-terminating decimal expansion”

Pada beberapa kasus operasi pembagian pada tipe data java.math.BigDecimal bisa terjadi error seperti ini:

Exception in thread “main” java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

Berikut contoh kode program nya:

import java.math.BigDecimal;

/**
 * Test case for "java.lang.ArithmeticException:
 * Non-terminating decimal expansion" error with
 * BigDecimal.
 *
 * @author JM
 *
 */

public class TestBigDecimal {

    public static void main(String[] args) {

        String returnVal = TestBigDecimal.divide("1", "5");

        System.out.println("Test #1: returnVal = " + returnVal);

        returnVal = TestBigDecimal.divide("1", "2");

        System.out.println("Test #2: returnVal = " + returnVal);

        // Test(#3) will fail as the quotient (returnVal)
        // is a non-terminating decimal value.

        returnVal = TestBigDecimal.divide("1", "3");

        System.out.println("Test #3: returnVal = " + returnVal);
    }

    /**
     * Pembagian val1 dengan val2 mengembalikan nilai sebagai String.
     *
     * @param val1
     * @param val2
     * @return value as String
     */
    public static String divide(String val1, String val2) {

        BigDecimal v1 = new BigDecimal(val1);

        BigDecimal v2 = new BigDecimal(val2);

        return v1.divide(v2).toPlainString();

    }
}

Pada contoh diatas akan menghasilkan output:

Test #1: returnVal = 0.2
Test #2: returnVal = 0.5
Exception in thread “main” java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(Unknown Source)
at com.jm.client.TestBigDecimal.divide(TestBigDecimal.java:34)
at com.jm.client.TestBigDecimal.main(TestBigDecimal.java:20)

Untuk mengatasi masalah ini perlu dituliskan parameter tambahan pada methode divide, seperti misalnya presisi/ketelitian bilangan dan juga RoundingMode, seperti contoh berikut ini:


import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Test case for "java.lang.ArithmeticException:
 * Non-terminating decimal expansion" error with
 * BigDecimal.
 *
 * @author JM
 *
 */
public class TestBigDecimal {

    public static void main(String[] args) {

        String returnVal = TestBigDecimal.divide("1", "5");

        System.out.println("Test #1: returnVal = " + returnVal);

        returnVal = TestBigDecimal.divide("1", "2");

        System.out.println("Test #2: returnVal = " + returnVal);

        // Test(#3) will now work as we have provided a scale
        // and a rounding mode to the divide() method

        returnVal = TestBigDecimal.divide("1", "3");

        System.out.println("Test #3: returnVal = " + returnVal);

    }

    /**
     * Pembagian val1 dengan val2 mengembalikan nilai sebagai String.
     *
     * @param val1
     * @param val2
     * @return value as String
     */
    public static String divide(String val1, String val2) {

        BigDecimal v1 = new BigDecimal(val1);

        BigDecimal v2 = new BigDecimal(val2);

        return v1.divide(v2, 2, RoundingMode.HALF_UP).toPlainString();

    }
} 

Outputnya kira-kira seperti ini:

Test #1: returnVal = 0.20
Test #2: returnVal = 0.50
Test #3: returnVal = 0.33

Sumber: