MySQL中浮点数
主要采用double(M,D)和decimal(M,D)两种。不显式指定长度和小数位数时,double默认double(0,0),decimal(10,0)。底层double是浮点数,decimal底层是字符串存储。double不能精确存储对应值,只能取近似值
设置精度后截断方式不同,double是五舍六入,decimal是四舍五入。
列num设置double(0,0) 值12.12和3.03 。
select sum(num) from account ;
//15.149999999999999
列num设置decimal(10,2)得到15.15
列num设置decimal(10,3)得到15.150
列num设置double(10,2)得到15.15
因此默认的double不设置精度时有一定概率出现精度问题。对于精度较高要求场景如涉及钱建议还是decimal存储。
Java中浮点数
java中double类型无法指定精度,BigDecimal类专门用来精确计算
double类型计算可能会出现精度丢失情况,计算结果不可控,如下代码,test1中计算符合预期,test2中计算不符合预期。
@Test
public void test1(){
double a = 1.25;
double b = 2.56;
System.out.println(a+b);
System.out.println(b-a);
System.out.println(a*b);
System.out.println(b/a);
if (b-a==1.31){
System.out.println("OK");
}
}
@Test
public void test2(){
System.out.println(0.1+0.2);
System.out.println(1.0-0.8);
System.out.println(4.015*100);
System.out.println(123.3/100);
double amount1 = 2.15;
double amount2 = 1.11;
if (amount1 - amount2 == 1.04)
System.out.println("OK");
}
Java中计算浮点数使用BigDecimal专门用来处理该问题,指定精度及四舍五入规则。