1. RandomAccessFile中writeInt的原理是什么?
先看源码:
public final void writeInt(int v) throws IOException {
write((v >>> 24) & 0xFF);
write((v >>> 16) & 0xFF);
write((v >>> 8) & 0xFF);
write((v >>> 0) & 0xFF);
//written += 4;
}
- “>>>” 表示无符号右移
- “&”:表示与操作 1&0 =0 1&1 =1
- “& 0xFF ”相当于截断,因为0xFF (16进制) = 11111111(二进制),这样操作保留低8位数字,高为补0
因为RandomAccessFile中的write()方法每次只能写入1个字节,而int数据类型占用4个字节,因此第1次写入时,先右移3个字节,获取高8位值,& 0xFF后将前面的0去掉,以此类推。
举例,int i = 2000,二进制为00000000 00000000 00000111 11010000
第1次右移24位,等于00000000 00000000 00000000 00000000,& 0xFF后获取高八位为00000000
第2次右移16位,等于00000000 00000000 00000000 00000000,& 0xFF后获取第二个八位为00000000
第3次右移8位,等于00000000 00000000 00000000 00000111,& 0xFF后第三个八位为00000111
第4次不右移,00000000 00000000 00000111 11010000 & 0xFF后第四个八位等于11010000
这样就把这个数字依次写入了。
2. 为什么java byte数值范围是 -128-127?
- 前提条件:一个字节有8位,第1位为符号位
- 最大值为正数,第1位为0,为使其最大,其他位补1,因此最大值等于01111111(毋庸置疑),为128
- 最小值位负数,第一位为1,为让这个负数最小,其他位只能补0,因此最小值等于10000000,为-127
- 注意01111111和10000000在这里都是补码
计算机都是用补码表示的:补码计算法定义:非负数的补码是其原码本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1
有关补码的介绍:
https://blog.csdn.net/lusa1314/article/details/83268873
https://www.jianshu.com/p/4e5e335af57c
3. 十六进制为FF对应的java数值为-1?
注意计算机都是用补码表示的
1的二进制原码、反码、补码为0000 0001
-1的二进制原码为1000 0001,反码为1111 1110,补码为1111 1111= FF(十六进制)
再看一个数字-48,对应的16进制是什么?
原码1011 0000 反码 1100 1111 补码 1101 0000= d0(十六进制)
网友评论