Java按位取反(~)的前导零作用及二进制数值歧义问题问询
Java按位取反(~)运算与补码的单射性问题解析
核心前提:Java的int是固定32位有符号补码类型
Java里的int类型从设计上就被定义为32位有符号整数,全程采用补码编码规则存储和解析数值,这是理解所有问题的基础——不存在“机器分不清”的情况,因为规则是固定的。
为什么不存在歧义?
你觉得11111111 11111111 11111111 11111101既可以是-3又可以是“约-20亿”,本质是混淆了两种不同的编码规则:
- 按照Java
int的有符号补码规则:最高位是符号位,1代表负数,此时这个二进制串对应的数值是-3。 - 如果你强行把它当成无符号整数解读:最高位不再是符号位,此时数值是
4294967293(约42亿),但Java的int类型根本不支持无符号解读,除非手动调用Integer.toUnsignedLong()这类方法转换类型。
按位取反的本质与补码特性
按位取反~是对32位中的每一位做0变1、1变0的操作,结果依然是int类型,所以必然按补码规则解析:
- 对于正数
n,~n的结果等价于-(n+1),这是补码的固有特性:
以2为例,二进制是00000000 00000000 00000000 00000010,取反后得到11111111 11111111 11111111 11111101。按照补码转原数的规则,负数的补码取反加1得到绝对值:这个串取反是00000000 00000000 00000000 00000010,加1后是3,所以原数为-3。
关于单射性的误解
单射的定义是“每个输入对应唯一输出”,但这个对应关系是基于同一规则的:
在Javaint的32位有符号补码规则下,每一个32位二进制串都唯一对应一个int值,每一个int值也唯一对应一个32位二进制串,是严格的双射关系,完全符合单射要求。你觉得违反单射,是同时用了“有符号补码”和“无符号”两套规则去解读同一个二进制串,这属于跨规则的混淆,不是int类型本身的映射问题。
内容的提问来源于stack exchange,提问作者LeoAlmDiniz
相关产品推荐
相关产品推荐

