目录
1.2、案例2(不同类型进行运算,强转结果使其与接收的数据类型一致)
前言
前面笔者带着大家对《基本数据类型》有了了解,也对《基本数据类型之间的转换以及字面值》进行了整理概括,那我们了解了这些要干什么呢?它会运用在哪里呢?感觉有很多人有这个疑问吧。今天笔者带大家来学习一下《运算规则》。
一、运算规则
我们在写任何程序的时候,都少不了计算,加也好减也罢。他都是有一些规范的,接下来笔者带大家一起来认识一下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
}
以上就是此次笔者带来的内容了,有什么疑问或者有什么建议可以评论区告诉我,谢谢大家的支持!!!