java中int,float,double的运算问题,BigDecimal加减乘除计算

本文探讨了Java中int、float、double运算存在的问题,并重点介绍了BigDecimal类用于精确计算的特点。详细讲解了BigDecimal的用法,包括构造器、常用方法如加减乘除,并提到了舍入模式和比较方法。还给出了格式化输出的例子,强调在商业计算中使用BigDecimal的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。

唔,其实里面就是一个工具类,加减乘除、保留两位小数。一共5个方法。。。emmmm.....为啥分这么高呢。因为宝宝想分想疯了。 附代码,有土豪就打赏打赏,没土豪的直接拿去使吧。 package cn.cisdom.base.utils; import java.math.BigDecimal; import java.text.DecimalFormat; public class Calculation { public static final DecimalFormat df = new DecimalFormat("######0.00"); /** * @methodName format2point * @desc 保留两位小数点 * @param value * @return java.lang.String * @author xm * @create 2018/6/7 12:03 **/ public static String format2point(Number value) { return df.format(value); } public static Double add(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param value1 * 减数 * @param value2 * 被减数 * @return 两个参数的差 */ public static Double sub(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * * @param value1 * 被乘数 * @param value2 * 乘数 * @return 两个参数的积 */ public static Double mul(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.multiply(b2).doubleValue(); } /** * 提供精确的运算。 * * @param value1 * 数 * @param value2 * 被数 * @return 数/被数 */ public static Double div(Number value1, Number value2) { //MathContext mc = new MathContext(2, RoundingMode.HALF_DOWN);//精度为2,舍入模式为大于0.5进1,否则舍弃 BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.divide(b2).doubleValue(); } public static void main(String[] args) { Double aDouble=Calculation.add(56.9, 1.67); System.out.println(aDouble); Double bDouble=Calculation.sub(99.2,aDouble); System.out.println(bDouble); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值