“3.9 直接常量”主要讲的是编程语言中的进制的概念,众所周知计算机使用的2进制做存储和计算的。我们平时涉及到比较多的就是10进制,计算机中还有8进制和16进制的概念。比如我们使用0x开头代表是16进制,用0开头代表8进制。同样为了区分跟整数一样数值的短浮点数和长浮点数,我们通常会在数字的结尾使用f或F,d或D来表示。下面举例说明上面的描述:
importstaticnet.mindview.util.Print.*; publicclassLiterals { publicstaticvoidmain(String[] args) { inti1=0x2f; // Hexadecimal (lowercase) print("i1: "+Integer.toBinaryString(i1)); inti2=0X2F; // Hexadecimal (uppercase) print("i2: "+Integer.toBinaryString(i2)); inti3=0177; // Octal (leading zero) print("i3: "+Integer.toBinaryString(i3)); charc=0xprint("c: "+Integer.toBinaryString(c)); byteb=0x7f; // max byte hex value print("b: "+Integer.toBinaryString(b)); shorts=0x7fff; // max short hex value print("s: "+Integer.toBinaryString(s)); longn1=200L; // long suffix longn2=200l; // long suffix (but can be confusing) longn3=200; floatf1=1; floatf2=1F; // float suffix floatf3=1f; // float suffix doubled1=1d; // double suffix doubled2=1D; // double suffix // (Hex and Octal also work with long) } }
/* Output:
i1: 101111
i2: 101111
i3: 1111111
c: 1111111111111111
b: 1111111
s: 111111111111111
*///:
ffff; // max char hex value
与进制有关的概念和表示方式以及他们之间的相互转换,这边就不多介绍了,计算机基础课程里开始就会学习这部分,跟刚开始学习数学的加减法差不多。我们在编程语言中,通过一些函数或者操作符即可完成进制的转换。这一块实际工作中使用的不是很多,除非你是做算法方面或者底层硬件方面或者通过底层协议跟其他系统通信会涉及到这块,可以暂时了解一下。这一小节还介绍了指数计数法,在Java中使用的也不多,可能没有做过数据科学数值计算方面的需求,主要是表示次方,比如:
publicclassExponents { publicstaticvoidmain(String[] args) { // Uppercase and lowercase ‘e’ are the same: floatexpFloat=1.39e-43f; expFloat=1.39E-43f; System.out.println(expFloat); doubleexpDouble=47e47d; // ‘d’ is optional doubleexpDouble2=47e47; // Automatically double System.out.println(expDouble); } }
/* Output:
1.39E-43
4.7E48
*///:~
1.39 x e-43表示的是1.39 x 2.718-43,程序里面表现的很不直观,e代表自然对数的基数,Java中用Math.E表示。Java也有专门的第三方类库做数据科学处理,提供了更丰富的数学中的表达方式,包括矩阵,向量等,尤其是与AI有关的库,肯定会使用到高等数学中的运算。实际工作中可能会用到,但是真的不多。
“3.10 按位操作符”和“3.11 移位操作符”主要是对二进制位进行操作的讲解。二进制位又叫比特,bit,由0、1组成的。bit是计算机内存中的最小单位。计算机其他的存储单位都是通过bit换算而来的,比如Byte、KB、MB、GB、TB等等,他们的换算关系自己查阅相关资料和书籍。现在我们只要了解的1Byte=8bit这个换算,因为我们的按位操作和移位都是操作这8bit。
假设我们有两个8位二进制数:A = 10101010(十进制:170)和B = 11001100(十进制:204)。
1、按位与操作(&):
按位与操作将两个数的每个对应位进行逻辑与操作,如果两个位都是1,结果为1,否则为0。
A: 10101010
B: 11001100
--------------
10001000 (结果:136)
2、按位或操作(|):
按位或操作将两个数的每个对应位进行逻辑或操作,结果为1的位将保留,如果两个位都是0,则结果为0。
A: 10101010
B: 11001100
--------------
11101110 (结果:238)
3、按位异或操作(^):
按位异或操作将两个数的每个对应位进行逻辑异或操作,结果为1的位表示两个对应位不同,否则为0。
A: 10101010
B: 11001100
--------------
01100110 (结果:102)
4、左移位操作(<<):
左移位操作将一个数的二进制表示向左移动指定的位数,右侧用0填充。
A: 10101010
A << 2:
10101000 (结果:168)
5、右移位操作(>>):
右移位操作将一个数的二进制表示向右移动指定的位数,左侧用原始符号位填充(对于有符号数)或用0填充(对于无符号数)
B: 11001100
B >> 2:
00110011 (结果:51)
书中对这块写了一些文字描述,没有这些例子,我感觉用个例子先让读者感觉一下这些操作是啥可能比较重要,也有可能书的作者认为这样去介绍计算机基本教程。总之,这一部分很底层的知识并没有太多深度的思想和编程技巧,以后实际开发你可能几乎看不到这块的应用,但是如果你看一下框架或者算法库的源码你会看到这些操作符的使用。好处就是提高代码执行效率。不好的地方就是看不懂。书中的代码例子可以自己运行一下,主要是借助Java提供的函数做一些转换打印输出,还有操作符的结合使用,多跑跑代码会给你更加感性的认识。