java中int,float,double的运算问题,BigDecimal加减乘除计算
1.两个int型数字相除,如果除数比被除数大很多,结果会为0.此时需要对其中一个数进行强制类型转换(float / double)即可输出正确结果
public static void main(String[] args){
String a="5";
String b="200";
float d=inta/intb;//直接除
float d2=(float)inta/intb;//被除数强制转型float
float d3=inta/(float)intb;//除数强制转型float
float d4=(float)inta/(float)intb;//都强制转换
//分别输出
System.out.println(d);
System.out.println(d2);
System.out.println(d3);
System.out.println(d4);
2.Java中的浮点数类型float和double不能够进行精确运算。这个问题有时候非常严重。比如,经过double型直接计算,1.4×1.5有时会得出2.0999999999999996的结果,但实际上,应该得到2.10。而且,类似的情况并不仅限于乘法计算。
BigDecimal用法详解
-
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。
-
双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。
-
float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。
-
BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。
-
构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
常用方法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
abs() BigDecimal对象中的值取绝对值,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。
特别注意
其实divide方法有可以传三个参数
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
第一参数表示除数, 第二个参数表示小数点后保留位数,
第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式,有下面这几种
ROUND_UP //向远离0的方向舍入;在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
ROUND_DOWN //向零方向舍入;在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
ROUND_CEILING //向正无穷方向舍入;如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同; 如果为负,则舍入行为与 ROUND_DOWN 相同。
ROUND_FLOOR //向负无穷方向舍入;如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同。
ROUND_HALF_UP //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式
格式化及例子
利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。
创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。
public static void main(String[] args) {
NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用
NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用
percent.setMaximumFractionDigits(3); //百分比小数点最多3位
BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额
BigDecimal interestRate = new BigDecimal("0.008"); //利率
BigDecimal interest = loanAmount.multiply(interestRate); //相乘
System.out.println("贷款金额:\t" + currency.format(loanAmount));
System.out.println("利率:\t" + percent.format(interestRate));
System.out.println("利息:\t" + currency.format(interest));
}
运行结果如下:
贷款金额: ¥15,000.48
利率: 0.8%
利息: ¥120.00
BigDecimal比较
BigDecimal是通过使用compareTo(BigDecimal)来比较的
public static void main(String[] args) {
BigDecimal a = new BigDecimal("1");
BigDecimal b = new BigDecimal("2");
BigDecimal c = new BigDecimal("1");
int result1 = a.compareTo(b);
int result2 = a.compareTo(c);
int result3 = b.compareTo(a);
System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
打印结果是:-1、0、1,即左边比右边数大,返回1,相等返回0,比右边小返回-1。
注意不能使用equals方法来比较大小。
使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。
总结
(1)商业计算使用BigDecimal。
(2)尽量使用参数类型为String的构造函数。
(3) BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。