做者:叄滴水
來源:https://blog.csdn.net/qq_3028...java
電商項目開發時確定少不了金額計算,金額計算時有不少讓人坑人的地方,在此記錄,以避免被坑。mysql
多精度不能直接計算,會存在經度缺失的問題。面試
public static void main (String[] args) { double num1 = 1; double num2 = 31.2; double num3 = 323.03; System.out.println (num1+num2+num3); /** * 355.22999999999996 */ }
如上代碼,3 個數值想加以後卻得出了一個很長的數值。spring
在 java 開發中能夠經過 BigDecimal 進行數值類型的計算,詳細可到 BigDecimal 工具類。sql
數據庫也是同樣,mysql中有float和double類型,經過sql直接累加數據也會有精度缺失的狀況。若是要精確的數值計算,要使用mysql的decimal類型。數據庫
public static void main(String[] args) { Integer i1 = 100; Integer i2 = 100; Integer i3 = 200; Integer i4 = 200; System.out.println(i1==i2); // true System.out.println(i3==i4); // false }
如上代碼很神奇,一樣是數值比對100的時候能夠經過雙等號返回true。200就返回false。intellij-idea
這是由於Integer的valueOf()方法。ide
//Integer的valueOf方法 public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
在[-128,128]之間的數,能夠經過雙等於比對成功,以外的數值就會返回一個new一個新的Integer,所以會返回false。工具
Double的比較就簡單一點,雙等於比對全是false。這是由於Double直接是返回了一個新的Double。
//Double的valueOf方法 public static Double valueOf(String s) throws NumberFormatException { return new Double(parseDouble(s)); }
在數值比對的時候亂的樣子,那我發現他們都有eq方法,經過這個方法比對能夠嗎?編碼
能夠的,無論是Integer仍是Double都存在一個equas方法,經過這個方法便可進行數值比對。可是這個方法不是很完美。
public static void main (String[] args){ Double i1 = 100d; System.out.println(i1.equals ("100")); //false }
如上所示,由於太多的人都知道字符串類型不能用雙等號進行比對,要用eq方法進行比對其value。這樣會讓不少人誤覺得Integer和Double類型也是如此,並且在編碼的時候如上這種寫法也沒有報錯,會認爲都是100確定會返回true。恰巧這種想法是錯誤的。
public boolean equals(Object obj) { return (obj instanceof Double) && (doubleToLongBits(((Double)obj).value) == doubleToLongBits(value)); }
Double的eq方法入參是Object類型,所以無論傳入什麼類型都不會報錯。i1.equals ("100")這種就是雙精度和字符進行比對,這兩個永遠都不可能返回true。正確的寫法應該是i1.equals (100d)。
可是儘管屢次提醒,可是仍是會有不認真的開發小夥伴錯誤,所以,可使用Double.compareTo方法,這個方法和eq方法相似,可是有編譯的異常,這樣可有效的提醒開發人員。
public static void main (String[] args){ Double i1 = 100d; System.out.println(i1.compareTo (100d)); //0 System.out.println(i1.compareTo (1d)); //1 }
小學的時候就講過,進行除法運算時,除以0是沒有意義的,開發過程當中也是如此, 發現可能存在除以0的場景要特別注意,程序不會拋出異常,居然會返回一個字符串!雖然這種場景很少,可是仍是須要了解一下。
1除以0的場景:
public static void main(String[] args) { Double d = 1d; double v = d / 0d; System.out.println(v); //Infinity }
0除以0的場景:
public static void main(String[] args) { Double d = 0d; double v = d / 0d; System.out.println(v); //NaN }
public static void main(String[] args) { Float f = 12312.12f; System.out.println(f.doubleValue()); System.out.println(Double.parseDouble (f.toString ())); //12312.1201171875 //12312.12 }
Float類中有一個doubleValue方法,返回值是一個double類型,這樣會很容易的覺得這是float轉換double類型。可是轉換以後精度缺失了,只能乖乖的換一種方式轉換。
近期熱文推薦:
1.600+ 道 Java面試題及答案整理(2021最新版)
2.終於靠開源項目弄到 IntelliJ IDEA 激活碼了,真香!
3.阿里 Mock 工具正式開源,幹掉市面上全部 Mock 工具!
4.Spring Cloud 2020.0.0 正式發佈,全新顛覆性版本!
以爲不錯,別忘了隨手點贊+轉發哦!