Java深海拾遺系列(5)--- 精度計算中的BigDecimal,double和float

FeelTouch發表於2019-04-03

在金融計算中,必須要使用BigDecimal,double和float都不適合

計算機進行的是二進位制運算,我們輸入的十進位制數字會先轉換成二進位制,進行運算後再轉換為十進位制輸出。double和float提供了快速的運算,然而問題在於轉換為二進位制的時候,有些數字不能完全轉換,只能無限接近於原本的值,這就導致了你看到的不正確的結果。

“BigDecimal可以表示任意精度的小數,並對它們進行計算。但要小心使用 BigDecimal(double) 建構函式,因為它會在計算的過程中產生舍入誤差。最好要使用基於整數或 String 的建構函式來建立BigDecimal物件。

2 / 0的時候程式會報java.lang.ArithmeticException的錯誤,那麼你知道2.0 / 0的結果嗎?”結果是Infinity(英菲尼迪),。其實就是無窮的意思。不僅有正無窮大,還有負無窮大,甚至還有一個叫做NaN的特殊值。NaN代表‘不是一個數字’。這些值的存在是為了在出現錯誤條件時,程式還可以用特定的值來表示所產生的結果。這些錯誤的情況包括算術溢位、給負數開平方根,還有您說的除以 0 等。

 

一道關於陣列的問題,你稍等一下,我在紙上寫一下。”

int[] a = {1, 2, 3, 4}
int[] b = {2, 4}
int[] c = {1, 3}
int[] d = {2}

“有這樣四個陣列,要求每個陣列只留一個唯一的元素。也就是說,a、b、c、d四個陣列之間的元素不能相同,你打算怎麼做呢?

import java.util.ArrayList;

public class Distinct {

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4};
        int[] b = {2, 4};
        int[] c = {1, 3};
        int[] d = {2};

        int[][] input = {a, b, c, d}; 

        //記錄每個陣列留下的唯一的元素
        ArrayList<Integer> result = new ArrayList<Integer>();

        //記錄每個陣列留下的唯一元素在陣列中的位置
        ArrayList<Integer> index = new ArrayList<Integer>(); 

        int row = 0;
        int column = 0;
        do {
            boolean isBacktrack = false; //記錄當前狀態,是否是回溯
            while(column < input[row].length) {

                Integer current = input[row][column];
                //當前元素是否已存在結果集中
                boolean isContained = result.contains(current);;

                //若當前元素不存在結果集中,將該元素加入結果集,並遍歷下一行
                if(isContained == false) {
                    result.add(current);
                    index.add(column);
                    column = 0;
                    row++;
                    break;
                }
                //如果當前元素已經存在結果集中,並且已經到達本行最後一個元素,則回溯一行
                else if(column + 1 == input[row].length) {
                    result.remove(result.size() - 1);
                    column = index.get(index.size() - 1) + 1;
                    index.remove(index.size() - 1);
                    row--; //回溯一行
                    isBacktrack = true;
                    break;
                }
                column++;
            }
            //如果是回溯,判斷列數是否超過該行的界限,如果超過了,再回溯一行
            if(isBacktrack && column == input[row].length) {
                result.remove(result.size() - 1);
                column = index.get(index.size() - 1) + 1;
                index.remove(index.size() - 1);
                row--; //回溯一行
                isBacktrack = true;
            }

        }while(row < input.length);

        //把 result 中的每個元素賦給相應的陣列
        for(int i = 0; i < result.size(); i++) {
            input[i] = new int[] {result.get(i)};
        }

        //列印每個陣列的元素
        for(int[] i: input) {
            System.out.println(i[0]);
        }
    }
}

 

相關文章