目录

前言

一、运算规则

1、不同类型运算

1.1、案例1(不同类型进行运算,结果与最大数据类型一致)

总结

1.2、案例2(不同类型进行运算,强转结果使其与接收的数据类型一致)

总结

1.3、案例3(加减乘除)

2、运算时的类型变化

2.1、案例1(byte)

2.2、案例2(short)

2.3、案例3(char)

3、整数运算溢出

3.1、案例1

4、浮点数运算不精确

4.1、案例1

4.2、案例2

5、浮点数的特殊值

5.1、案例1


前言

        前面笔者带着大家对《基本数据类型》有了了解,也对《基本数据类型之间的转换以及字面值》进行了整理概括,那我们了解了这些要干什么呢?它会运用在哪里呢?感觉有很多人有这个疑问吧。今天笔者带大家来学习一下《运算规则》。


一、运算规则

        我们在写任何程序的时候,都少不了计算,加也好减也罢。他都是有一些规范的,接下来笔者带大家一起来认识一下Java的5条运算规则。


1、不同类型运算

在不同数据类型进行运算时,计算结果的数据类型,与最大的一致。

1.1、案例1(不同类型进行运算,结果与最大数据类型一致)

首先我们创建两个不同整数类型的变量

public static void main(String[] args) {
	int x = 10; //int类型是4字节的
    long y = 3L; //long类型是8字节的
}

随后我们思考一个问题,如果x与y相加。我们需要以什么数据类型来接收呢?

此时呢我感觉各位应该会想到两个数据类型(int/long),那我们根据情况都来看一下:

1)如果我们使用int来接收

int count = x + y;

 上图可以看出,如果我们以int来接收就会出现报错“Type mismatch: cannot convert from long to int”,说的是“类型不匹配:无法从long转换为int”也就是说我们不能使用int来接收他们相加的和

2)使用long来接收

long count = x + y;

 可以看到,使用long来接受x与y的和是可以正常进行计算的。

总结:

通过上面的验证,我们可以看到如果我们对两个不同类型的变量进行运算时,它默认得到的结果会与最大的数据类型一致。当然如果我们想以小的数据类型来接收,也不是不可以,这里就需要了解“强转”


1.2、案例2(不同类型进行运算,强转结果使其与接收的数据类型一致)

还是以刚刚的两个变量为例:

int x = 10; //int类型是4字节的
long y = 3L; //long类型是8字节的

我们使用强转,将结果(long类型),转换成我们接收的int类型

public static void main(String[] args) {
	int x = 10; //int类型是4字节的
	long y = 3L; //long类型是8字节的
		
	//使用强转,将结果(long类型),转换成我们接收的int类型
	int count = (int)(x + y);
		
	//打印结果查看
	System.out.println("x+y="+count);//打印结果为:x+y=13
}

可以看到,我们使用强转后,将本是long类型的结果转换成了int类型,成功并交给了我们int 类型的 count来接收。

总结

如果我们对两个不同类型的变量进行运算时,它默认得到的结果会与最大的数据类型一致。但是当我们使用强转后,就可以将原本是long类型的结果值,转换成了int。并成功接收打印。


1.3、案例3(加减乘除)

上面其实我们已经做过加法的运算了,但是是整数与整数之间的,这里我就以整数与小数之间进行演示了。

public static void main(String[] args) {
	int x = 10; //int数据类型是4字节
	double y = 10.6; //double数据类型是8字节
}

1)相加

结果会根据运算的最大数据类型一致,所以我们需要使用double来接收

//1.相加
double count = x+y; //刚才我们说过,如果两个数进行运算,结果会根据运算的最大数据类型一致,所以我们需要使用double来接收
System.out.println(count); //打印结果为:20.6

大家想一想,如果这里我们使用强转接收会怎么样?

int count1 = (int)(x+y);//如果我们强转它的数据类型,大家想一下
System.out.println(count1);//打印结果为:20,他将后面的0.6直接舍弃了

通过实验其实我们可以看到,他将结果后的小数位直接舍弃掉了

2)相减

修改刚刚定义的变量,并进行减法运算

x = 10; //int数据类型是4字节
y = 3.6; //double数据类型是8字节

//2.相减
double reduce = x-y; //刚才我们说过,如果两个数进行运算,结果会根据运算的最大数据类型一致,所以我们需要使用double来接收
System.out.println(reduce); //打印结果为:6.4

//2.1.int接收相减的值
int reduce1 = (int)(x-y);//这里我们需要强转
System.out.println(reduce1);//打印结果为:6,他将后面的0.4直接舍弃了

3)相乘

x = 10; //int数据类型是4字节
y = 3.6; //double数据类型是8字节

//3.相乘
double ride = x*y; //刚才我们说过,如果两个数进行运算,结果会根据运算的最大数据类型一致,所以我们需要使用double来接收
System.out.println(ride); //打印结果为:36.0
		
//3.1.int接收相乘的值
int ride1 = (int)(x*y);//使用强转接收
System.out.println(ride1);//打印结果为:36,小数位直接舍弃了

4)相除

x = 21; //int数据类型是4字节
y = 5; //double数据类型是8字节

//4.相除
double except = x/y; //刚才我们说过,如果两个数进行运算,结果会根据运算的最大数据类型一致,所以我们需要使用double来接收
System.out.println(except); //打印结果为:4.2
		
//4.1.int接收相除的值
int except1 = (int)(x/y);//使用强转接收
System.out.println(except1);//打印结果为:4,小数位直接舍弃了

2、运算时的类型变化

byte、short、char三种比int小的整数,运算时会先自动转换成int

2.1、案例一(byte)

public static void main(String[] args) {
	/**
	  * 0.验证byte在运算时会先自动转换成int
	  */
	//1.先定义两个byte类型的值
	byte a1=10;//10默认是int类型,但是底层自动转换byte
	byte a2=3; //这里的3也是同理
		
	//2.错误运算
	//byte a3=a1+a2;//错误的,a1+a2的结果会自动认为是int类型,赋值给byte就会大转小
	//byte a3=(byte)a1+(byte)a2;//编译错误,a1和a2计算结果都是int
		
	//3.正确运算
	byte a3=(byte)(a1+a2);//a1+a2的计算结果再强转类型
	System.out.println(a3);//打印结果为:13
}

2.2、案例二(short)

short其实和byte是一样的

public static void main(String[] args) {
	/**
	  * 0.验证short在运算时会先自动转换成int
	  */
	//1.定义一个byte类型的变量,一个short类型的变量。这里这样定义是为了验证两种比int小的值相加是否也是按int进行运算
	byte b1=10;
	short b2=20;
		
	//2.错误示范
	//short b3=b1+b2;//b1和b2结果就是int
		
	//3.正确示范
	short b3=(short)(b1+b2);//b1+b2的计算结果再强转类型
	System.out.println(b3);//打印结果为:30
}

2.3、案例三(char)

public static void main(String[] args) {
	/**
	  * 0.验证char在运算时会先自动转换成int
	  */
	//1.我们定义一个char类型的变量,看其是否可以和int相加
	char c1='中';//'中'的ASCII码是:20013
	int c2=c1+1; //使c1加1,我们发现却没有报错,证明我们的猜想是正确的,在运算是char类型的变量.默认是int类型
	System.out.println(c2);//打印结果为:20014 c1+1得到的结果
		
	//2.如果想使用char进行接收需要怎样操作呢
	//2.1.错误示范
	//char c3=c1+5;//c1+5也是会自动当做int
		
	//2.2.正确示范
	char c3=(char)(c1+5);
	System.out.println(c3);//打印结果为:"串","串"的ASCII码正是20014
}

通过验证,我们也可以看到在byte、short、char进行运算时,会先自动转换成int然后进行运算


3、整数运算溢出

整数运算,就相似于一个时钟,每当传入值超过了类型的最大接收范围,就会重新从最小值重新开始计算。如图(我们以byte的最大值和最小值为例):

没看明白没关系,可以看一下下面的案例,就搞懂了


3.1、案例1

获取byte、int、long的最大值,随后加1我们看看会发生什么。

public static void main(String[] args) {
    //1.byte
	byte b = Byte.MAX_VALUE;//获取byte最大值
	System.out.println(b);//打印结果为:127
		
	//1.1.byte模拟运算溢出
    /* 因为整数的字面值是int,两者相加结果为最大数据类型int。
     * 所以我们使用byte接收时需要进行强转。
     */
	byte b1 = (byte)(b + 1);//最大值+1
	System.out.println(b1); //打印结果为:-128
		
	//2.int
	int i = Integer.MAX_VALUE;//获取int最大值
	System.out.println(i);//打印结果为:2147483647
		
	//2.1.int模拟运算溢出
	int i1 = i + 1;//最大值+1
	System.out.println(i1);//打印结果为:-2147483648
	
	//3.long
	long l = Long.MAX_VALUE;//获取long最大值
	System.out.println(l);//打印结果为:9223372036854775807
		
	//3.1.long模拟运算溢出
	/*
	 * 注意有的人在这可能就疑惑了,为啥这里不需要强转呢??因为整数的字面值时int类型,
	 * int与long相加我们又是以long类型接收的,所以并不需要进行强转
	 */
	long l1 = l + 1;//最大值+1。
		
	System.out.println(l1);//打印结果为:-9223372036854775808
		
	}

4、浮点数运算不精确

由于Java有些小数无法精确的用二进制进行表示(这里请大家记住这个结论), 所以某些小数在运算时会出现不精确的情况。

注:根本原因是:十进制值通常没有完全相同的二进制表示形式;十进制数的二进制表示形式可能不精确。只能无限接近于那个值


4.1、案例1

public static void main(String[] args) {
	/**
	  * 我们看一下小数之间的运算
      */
	System.out.println(0.1+0.2);//打印结果为:0.30000000000000004。
    //出现了运算不精确的问题了,正常的话应该就是0.3才对

	System.out.println(0.2-0.1);//打印结果为:0.1。可以看到这个值是正确的

	System.out.println(0.6-0.5);//打印结果为:0.09999999999999998。
    //和上面的减法运算看来没什么区别,但是运算结果还是不精确

	System.out.println(0.3/0.1);//打印结果为:2.9999999999999996
}

通过上面的案例我们可以看到,小数之间在运算时会出现运算结果不精确的问题。

那有的朋友就要问了,那我们如果使用小数运算怎么办呢???

当然在Java当中针对浮点数精确运算也是提供了方法


4.2、案例2

public static void main(String[] args) {
	/**
	  * 我们使用BigDecimal这个对象来解决浮点数运算不精确的问题
	  */
	BigDecimal x1=new BigDecimal("0.1");
	BigDecimal x2=new BigDecimal("0.2");
	BigDecimal x3=new BigDecimal("0.3");
	/*
	 * BigDecimal提供了add()方法,用于加法运算
	 * BigDecimal提供了subtract()方法,用于减法运算
	 * BigDecimal提供了multipy()方法,用于乘法运算
	 * BigDecimal提供了divide()方法用于触发运算
	 */
	//相加
	System.out.println("0.1+0.2="+x1.add(x2));//打印结果为:0.1+0.2=0.3
	
	//相减
	System.out.println("0.3-0.1="+x3.subtract(x1));//打印结果为:0.3-0.1=0.2
	
	//相乘
	System.out.println("0.1*0.03="+x1.multiply(x3));//打印结果为:0.1*0.03=0.03
	
	//相除
	System.out.println("0.2/0.1="+x2.divide(x1));//打印结果为:0.2/0.1=2
}

可以看到我们通过使用BigDecimal对象也是成功的解决了小数运算不精确的问题。

那有的朋友就要问了,BigDecimal是什么???

BigDecimal是Java在java.math包中提供的API类,用来对超过16位有效位的数进行精确的运算。这里我们还没讲到API所以先做了解就可以!


5、浮点数的特殊值

5.1、案例1:

public static void main(String[] args) {
	/**
	  * 0.浮点数的特殊值,有两种情况:
	  *   Infinty 无穷大
	  *   NaN -- not a Number 不是一个数字
	  */
	//1.Infinty
	//1.1.正数除以0的结果就是正无穷大
	System.out.println(3.12/0);//Infinity
	//1.2.负数除以0的结果就是负无穷大
	System.out.println(-3.12/0);//-Infinity
		
	//2.NaN
	System.out.println(0.0/0.0);//NaN
}

以上就是此次笔者带来的内容了,有什么疑问或者有什么建议可以评论区告诉我,谢谢大家的支持!!!


版权声明:本文为weixin_45757683原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_45757683/article/details/122121752