1. 程式人生 > >java中float,double型別運算的處理

java中float,double型別運算的處理

public class Test{
    public static void main(String args[]){
        System.out.println(0.05+0.01);
        System.out.println(1.0-0.42);
        System.out.println(4.015*100);
        System.out.println(123.3/100);
    }
}

你沒有看錯!結果確實是

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999

Java中的浮點數型別float和double不能夠進行運算,因為大多數情況下是正常的,但是偶爾會出現如上所示的問題。

這個問題其實不是JAVA的bug,因為計算機本身是二進位制的,而浮點數實際上只是個近似值,所以從二進位制轉化為十進位制浮點數時,精度容易丟失,導致精度下降。

java專門的小數運算類:BigDecimal型別,用於解決double和float小數運算更精準的計算。

根據平時工作需要,寫了一個工作類,方便使用:

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;


/**
 * 由於Java的簡單型別不能夠精確的對浮點數進行運算,這個工具類提供精確的浮點數運算,包括加減乘除和四捨五入。
 */
public class DoubleUtil { // 預設除法運算精度 private static final int DEF_DIV_SCALE = 10; /**#.## */ public static final String REG_1 = "#.##"; /** #,###.## */ public static final String REG_2 = "#,###.##"; // 這個類不能例項化 private DoubleUtil() { } /** * 去掉科學記數法 */ public static String toStr(double v1)
{ BigDecimal b1 = new BigDecimal(Double.toString(v1)); return b1.toPlainString(); } /** * 主要用於格式化金額 * @param v1 如:56,888,458,521 * @return */ public static String format(double v1) { NumberFormat numberFormat = new DecimalFormat(REG_2); String str = numberFormat.format(v1); return str; } /** * 主要用於格式化小數點 * @param v1 * @param reg * @return */ public static String format(double v1,String reg) { NumberFormat numberFormat = new DecimalFormat(reg); String str = numberFormat.format(v1); return str; } /** * 加法 */ public static double add(double v1, double ...v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); for (double vv : v2){ BigDecimal b2 = new BigDecimal(Double.toString(vv)); b1=b1.add(b2); } return b1.doubleValue(); } /** * 減法 */ public static double sub(double v1, double ...v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); for (double vv : v2){ BigDecimal b2 = new BigDecimal(Double.toString(vv)); b1=b1.subtract(b2); } return b1.doubleValue(); } /** * 乘法運算。 */ public static double mul(double v1,double ...v2) { BigDecimal b1=new BigDecimal(Double.toString(v1)); for (double vv : v2){ BigDecimal b2 = new BigDecimal(Double.toString(vv)); b1=b1.multiply(b2); } return b1.doubleValue(); } /** *除法運算,當發生除不盡的情況時,精確到 小數點以後10位,以後的數字四捨五入。 public static double div(double v1, double ...v2) { return div(DEF_DIV_SCALE,v1, v2); } */ /** * 提供(相對)精確的除法運算。 */ public static double div(double v1, double ...v2) { // if (scale < 0) { // throw new IllegalArgumentException( // "The scale must be a positive integer or zero"); // } BigDecimal b1 = new BigDecimal(Double.toString(v1)); for (double vv : v2){ BigDecimal b2 = new BigDecimal(Double.toString(vv)); b1=b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP); } return b1.doubleValue(); } /** * 提供精確的小數位四捨五入處理 */ public static double round(double v, int scale) { if (scale < 0) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal("1"); return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static String doubleWangFormatByObj(Object obj){ return doubleWangFormatByObj(obj, "0"); } public static String doubleWangFormatByObj(Object obj,String defaultValue){ if(obj==null){ return defaultValue; }else{ DecimalFormat df = new DecimalFormat("0.00"); return df.format(((Double)obj)/10000); } } public static String doubleFormatByObj(Object obj,String defaultValue){ if(obj==null){ return defaultValue; }else{ DecimalFormat df = new DecimalFormat("0.00"); return df.format(((Double)obj)); } } public static void main(String[] args) { double sum=0; System.out.println(DoubleUtil.doubleFormatByObj(sum,"0.00")); } }