java中float,double型別運算的處理
阿新 • • 發佈:2019-01-30
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"));
}
}