软件工程第二次课课堂总结
1、枚举类型用法总结
代码如下:
1 public class EnumTest { 2 3 public static void main(String[] args) { 4 Size s=Size.SMALL; 5 Size t=Size.LARGE; 6 //s和t引用同一个对象? 7 System.out.println(s==t); // 8 //是原始数据类型吗? 9 System.out.println(s.getClass().isPrimitive()); 10 //从字符串中转换 11 Size u=Size.valueOf("SMALL"); 12 System.out.println(s==u); //true 13 //列出它的所有值 14 for(Size value:Size.values()){ 15 System.out.println(value); 16 } 17 } 18 19 } 20 enum Size{SMALL,MEDIUM,LARGE};
运行结果如下:
首先,对于枚举类型,枚举的各元素为不同对象,位于内存中的不同位置,且枚举类型不属于原始数据类型,字符串可以转换成枚举类型。当遍历枚举类型中的所有值时,打印的是枚举类型中列举的各项。
对于枚举类型的变量,使用“==”和“equals()”方法是等价的。
2、原码、补码、反码的概念及应用
首先,原码、补码和反码实在二进制的基础上实现的,下面也将基于二进制数字描述这三个概念及其应用
原码:如,十进制数字7的原码为00000111,十进制数字-7的原码为10000111;第一位数字代表符号,如果是0则为正,如果是1则为负
反码:如,十进制数字7的反码为00000111,十进制数字-7的反码为11111000;正数的反码是其本身,负数的反码是其符号位不变,其余各位取反
补码:如,十进制数字7的补码为00000111,十进制数字-7的补码为11111001;正数的补码是其本身,负数的补码是其反码+1
计算机中存储的都是数的补码,正数的原码、反码、补码都是相同的;而负数的原码、反码、补码是不一样的,补码=原码取反+1(符号位不变)。所以,负数是按照它的补码输出的。
关于二进制数运算测试:
代码如下:
1 public class doubletest { 2 public static void main(String[] args) { 3 int num1=7; 4 int num2=-7; 5 int num3=5; 6 int num4=-5; 7 String b1 = Integer.toBinaryString(num1); 8 String b2 = Integer.toBinaryString(num2); 9 String b3 = Integer.toBinaryString(num3); 10 String b4 = Integer.toBinaryString(num4); 11 System.out.println("十进制:"+num1+" 二进制:"+b1); 12 System.out.println("十进制:"+num2+" 二进制:"+b2); 13 System.out.println("进行运算:"); 14 System.out.println("1、左移2位\n\t7:十进制:"+(num1<<2)+" 二进制:"+Integer.toBinaryString(num1<<2)+"\n\t-7:十进制:"+ 15 +(num2<<2)+" 二进制:"+Integer.toBinaryString(num2<<2)); 16 System.out.println("2、右移2位\n\t7:十进制:"+(num1>>2)+" 二进制:"+Integer.toBinaryString(num1>>2)+"\n\t-7:十进制:"+ 17 +(num2>>2)+" 二进制:"+Integer.toBinaryString(num2>>2)); 18 System.out.println("3、&运算\n\t7的二进制:"+b1+" 5的二进制:"+b3+"\n\t7&5二进制"+ 19 Integer.toBinaryString(7&5)+" 十进制:"+(7&5)); 20 System.out.println("4、|运算\n\t7的二进制:"+b1+" -5的二进制:"+b4+"\n\t7|-5二进制"+ 21 Integer.toBinaryString(7|-5)+" 十进制:"+(7|-5)); 22 System.out.println("5、^运算\n\t-7的二进制:"+b2+" 5的二进制:"+b3+"\n\t-7^5二进制"+ 23 Integer.toBinaryString(-7^5)+" 十进制:"+(-7^5)); 24 System.out.println("6、~运算\n\t7的二进制:"+b1+" 5的二进制:"+b3+" -7的二进制"+ 25 b2+" -5的二进制"+b4+"\n\t~7的二进制:"+Integer.toBinaryString(~7)+ 26 " ~5的二进制:"+Integer.toBinaryString(~5)+" ~-7的二进制:"+Integer.toBinaryString(~-7)+ 27 " ~-5的二进制:"+Integer.toBinaryString(~-5)); 28 } 29 }
测试结果:
可见,<<运算是将二进制数字全部左移n位,后面补0,>>运算是将二进制数字全部右移n位,正数前面补0,负数补1;
&运算是将二进制数字各位相比较,两数全为1才得1,否则得0
|运算是将二进制数字各位相比较,两数有一个是1则为1,都是0才得0
^运算是将二进制数字各位相比较,两数相同则为0,两数不同则为1
~运算即将二进制各位取反,0变1,1变0
3、double类型运算精确问题
测试代码:
1 public class doubletest { 2 public static void main(String[] args) { 3 System.out.println("0.05+0.01="+(0.05+0.01)); 4 System.out.println("1.0-0.42="+(1.0-0.42)); 5 System.out.println("4.015*100="+(4.015*100)); 6 System.out.println("123.3/100="+(123.3/100)); 7 } 8 }
测试结果:
为什么double类型的数值进行运算的时候得不到“数学上精确的结果”?
该问题的本质还是来源于二进制与十进制之间的转化,double类型的数值占用64bit,即64个二进制数,除去最高位表示正负符号的位,在最低位上一定会与实际数据存在误差(除非实际数据恰好是2的n次方),比如要用4bit来表示小数3.26,从高到低位依次对应2的1,0,-1,-2次幂,根据最上面的分析,应当在二进制数11.01(对应十进制的3.25)和11.10(对应十进制的3.5)之间选择。简单来说就是我们给出的数值,在大多数情况下需要比64bit更多的位数才能准确表示出来(甚至是需要无穷多位),而double类型的数值只有64bit,后面舍去的位数一定会带来误差,无法得到“数学上精确”的结果。
而在java中,为解决double类型数值运算封装了一个BigDecimal类,该类可以解决double类型运算不精确的问题。
关于BigDecimal类的构造器及方法介绍可见以下链接:https://www.jianshu.com/p/c81edc59546c
4、字符串连接测试:
代码如下:
1 public class test { 2 public static void main(String[] args) { 3 int X=100; 4 int Y=200; 5 System.out.println("X+Y="+X+Y); 6 System.out.println(X+Y+"=X+Y"); 7 } 8 }
测试结果如下:
可以看出当字符串前有+时,会先进行前面的运算,再判断后面是字符串,即X+Y+"=X+Y"相当于(X+Y)+"=X+Y",而当字符串在前是,会把+后面每个变量都转化为字符串型在进行字符串的连接