Java数值计算的总结

最近在做一些Java基础的练习OJ,其中大量涉及各种类型的混合计算,转换,精度计算以及日期推导。刷题的同时看看前辈们的讨论,在细节上感觉有许多新的认识。在此总结一下,以资备用。


#整型
整型,可以粗略的理解为整数,它又分为四种基本类型,byte,short,int,long。其基本数据长度与数值范围如下表。

类型长度取值范围
byte1字节-128-127
short2字节 − 2 − 15 − 2 15 − 1 -2^{-15}-2^{15}-1 2152151
int4字节 − 2 − 31 − 2 31 − 1 -2^{-31}-2^{31}-1 2312311
long8字节 − 2 − 63 − 2 63 − 1 -2^{-63}-2^{63}-1 2632631

强化一下记忆,回顾一下最基本的知识,1byte=8bit,每个bit就是一个0,1,所以去掉一位作为符号位,每种类型能够表示的范围就很好算了,当他们前面注明unsigned时,变为无符号数,其范围为 0 − 2 ( l e n × 8 − 1 ) − 1 0-2^{(len\times8-1)}-1 02(len×81)1

#浮点类型
浮点型,主要分为两类,float和double,他们分别是4字节和8字节。两者的区别在于长度和精度。double比float长了一倍,所以空间、处理速度什么的都要相应翻倍。使用时应尽量选择适当的。然而,我现在一般都只用double,这样好像不太好,我反省。

使用浮点型的数据类型时,还有个比较令人头痛的问题——精度,小数点前面的整数部分是用除余法获得的,而小数点后面的部分是用乘基数取整法得到的。如 0.2先0.2×2,得0.4取整数部分0作为小数的十分位,再0.4×2,得0.8,取整数0作为小数的百分位,一直重复上述步骤,直到所需的精度。故他的精度是令人捉急的,所以我们尽量不要用浮点数进行判断操作,即用“==”,这样可能永远都进不去这个if了。如果非要的话,比如在Junit里面做断言测试,那么可以采用精度范围来判断,一般可以采用“<10e-6”这种方式。

刚刚讨论了浮点数的精度问题,日常代码中我们最常做的就是把一个类型赋值给另一个类型,有些安全有些则不然,这就涉及到了各种类型间转换精度保证的问题。下图抄自《Java核心技术第一卷》,其中实线为精度安全的转换,虚线为精度丢失的转换。
这里写图片描述

然而工程中,很多时候需要精度有保障的浮点数计算,为了满足这个需求,BigDecimal和BigInteger类型就应运而生了,他们的加减乘除计算可以完美的保证运算精度,两个类型的用法一样,一个是针对小数的一个是处理整数的,其中BigDecimal类型的具体使用方式如下。

		BigDecimal n1 = new BigDecimal("3.6"); 
    	double five=2;
    	BigDecimal n2 = new BigDecimal(five);  
    	BigDecimal reslut = null;  
    	      	
    	reslut =  n1.add(n2);       							//加法  
    	System.out.println("3.6+2=" + reslut.doubleValue());  
    	     	
    	reslut  = n1.subtract(n2);  							//减法  
    	System.out.println("3.6-2=" + reslut.doubleValue());  
    	    
    	reslut  = n1.multiply(n2);      						//乘法
    	System.out.println("3.6*2=" + reslut.doubleValue());  
    	  
    	reslut  = n1.divide(n2);      							//除法  
    	System.out.println("3.6/2=" +reslut.doubleValue());  
    	
    	BigDecimal n3 = new BigDecimal("-1.5");
    	reslut  = n3.abs();      								//绝对值  
    	System.out.println("|-1.5|=" + reslut.doubleValue());  
    	
    	n1 = new BigDecimal("3.6"); 
    	n2 = new BigDecimal("1.2"); 
    	reslut  = n1.divide(n2);      							//除法  
    	System.out.println("3.6/1.2=" + reslut.doubleValue());  
    	reslut  = n1.divide(n2).stripTrailingZeros();      		//识别小数点  
    	System.out.println("3.6/1.2=" + reslut);  

这里写图片描述
#时间
时间也是平时计算时用的较多的内容,某日十天前是周几?某年某月第一个周三是几号?这些计算我刚刚碰到时,略加思索便开始大展拳脚写闰年判断方法,月份、星期的枚举,忙的不亦乐乎,但往往写完后各种bug蹦出来,杀人的心都有了。后来,知道还有Date、Calendar等类可供使用。其中Date类多用于记录时间,而计算时间则交给日历Calendar类来完成,其具体用法如下。

		Calendar cal=Calendar.getInstance();

		cal.add(Calendar.DAY_OF_MONTH, 15);

		String strDate=cal.get(Calendar.YEAR)+"年"+(cal.get(Calendar.MONTH)+1)+"月"+cal.get(Calendar.DATE)+"日";

		System.out.println("15天后的日期为:"+strDate);
				
		cal=Calendar.getInstance();
		
		cal.add(Calendar.DAY_OF_YEAR, -15);

		strDate=cal.get(Calendar.YEAR)+"年"+(cal.get(Calendar.MONTH)+1)+"月"+cal.get(Calendar.DATE)+"日";

		System.out.println("15天前的日期为:"+strDate);

![这里写图片描述](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcwNDI4MDAyNzQzNDU5?x-oss-process=image/format,png)

上述是简单的计算,还可以深入精确的毫秒计算。另外需要注意的一点是,Calendar类把月定位0-11,使用时需注意转换。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiba_zwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值