Java中存储⾦额⽤什么数据类型-BigDecimal
⽂章⽬录
1.引⼦
很早之前, 记得⼀次⾯试, ⾯试官问存储⾦钱⽤什么数据类型? 当时只知道8种数据类型(boolean, byte, short, int, long, float, double, char)的我, 回答了double, 因为我觉得double是双精度类型, 最适合, 但是⾯试官告诉我应该⽤BigDecimal! 最近在做⽀付的项⽬, 才对这种数据类型有了更多的了解;
结果是:1915.1799,⽽不是 1915.18,出现失真的问题。
解决办法(X):想办法把数据四舍五⼊然后存到数据库
出现问题:当多操作了⼏次后,直接到数据库检查⾦额是否正确的时候,失真问题依然存在,只不过存在于数据库⽽不是存在与程序。
原因:float和double都是浮点数, 都有取值范围,都有精度范围。浮点数与通常使⽤的⼩数不同,使⽤中,往往难以确定。常见的问题是定义了⼀个浮点数,经过⼀系列的计算,它本来应该等于某个确定值,但实际上并不是,⾦额必须是完全精确的计算,故不能使⽤double或者float。
解决办法:
在程序中存储⾦额的数据类型⽤:java.math.BigDecimal,在数据库中存储⾦额的数据类型⽤:decimal。
长度可以⾃定义,如10,⼩数点在项⽬中⽤的是2,保留2位⼩数。
此外还要注意的就是默认值,⼀定写成0.00,不要⽤默认的NULL,否则在进⾏加减排序等操作时,会带来转换的⿇烦。
SQL: 'amount' DECIMAL(10, 2) DEFAULT 0.00 NOT NULL COMMENT '⾦额',
bigdecimal除法保留小数2. 加减乘除
两个 BigDecimal 的值不能⽤ +、-、*、/ 来进⾏加减乘除
public static void main(String[] args){
BigDecimal x =new BigDecimal("1.3");
BigDecimal y =new BigDecimal("2.5");
// 加法 --> 3.8
BigDecimal add = x.add(y);
System.out.println(add);
// 减法 --> -1.2
BigDecimal subtract = x.subtract(y);
System.out.println(subtract);
// 乘法 --> 3.25
BigDecimal multiply = x.multiply(y);
System.out.println(multiply);
// 除法 --> 0.5 ,RoundingMode.HALF_UP 四舍五⼊
BigDecimal divide = x.divide(y, RoundingMode.HALF_UP);
System.out.println(divide);
}
3. ⼤⼩⽐较
两个BigDecimal值⽐较使⽤compareTo⽅法,⽐较结果有-1,0,1,分别表⽰⼩于, 等于, ⼤于
对于0,使⽤BigDecimal.ZERO表⽰
BigDecimal num = new BigDecimal("-3");
if(numpareTo(BigDecimal.ZERO)== -1){
System.out.println("num ⼩于 0");
}else if(numpareTo(BigDecimal.ZERO)==1){
System.out.println("num ⼤于 0");
}else if(numpareTo(BigDecimal.ZERO)==0){
System.out.println("num 等于 0");
}
4. ⼩数位数及四舍五⼊规则
setScale⽅法的第⼀个参数是⼩数位数,这个⽰例是保留2位⼩数,后⾯是四舍五⼊规则
public static void main(String[] args){
BigDecimal num =new BigDecimal("10.2621684798165165");
System.out.println("原型 = "+ num);
System.out.println("直接删除多余的⼩数位 = "+ num.setScale(2, BigDecimal.ROUND_DOWN));
System.out.println("进位 = "+ num.setScale(2, BigDecimal.ROUND_UP));
System.out.println("四舍五⼊,碰到5位进位 = "+ num.setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println("四舍五⼊,碰到5位舍弃 = "+ num.setScale(2, BigDecimal.ROUND_HALF_DOWN)); }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论