参考来源:https://www.cnblogs.com/yesiamhere/p/6675067.html
计算子网终止地址的长整形时发现一个工具类是这样实现的
子网起始地址的长整型+ ~ 子网掩码长整型
然而实际使用中发现这样算出来是一个很大的负数,深究发现问题出在~运算符上
~非运算,按位取反,但在实际中要考虑数据类型的实际位数。
如Java中整形为4个字节 即32位,长整型为8个字节 即64位,这边之所以出这个问题就是因为子网掩码使用了长整型,所以取反后得到一个很大的负数,导致最后结果出错!
~非运算
按子网掩码255.255.255.0来计算
其二进制表示为 11111111 11111111 11111111 00000000
长整型表示为 4294967040 取反为-4294967041
整形表示为 -256 取反为255
下面具体说为什么
看非运算过程
长整型:
长整型的二进制表示为
00000000 00000000 00000000 00000000 11111111 11111111 11111111 00000000
取反为
11111111 11111111 11111111 11111111 00000000 00000000 00000000 11111111
注意计算机中保存的都是补码,首位为1意味着是负数,计算负数的原码为 补码-1然后除符号位按位取反
补码-1
11111111 11111111 11111111 11111111 00000000 00000000 00000000 11111110
除符号位按位取反
10000000 00000000 00000000 00000000 11111111 11111111 11111111 00000001
即最后的结果为-(4294967040+1)=-4294967041
下面看整形:
整形:
整形的二进制表示:
11111111 11111111 11111111 00000000
按位取反为:
00000000 00000000 00000000 11111111
这是补码,首位符号位为0 表示正数,正数的原码即为补码
因此最后结果为255
可见实际中进行非运算要考虑到类型,否则结果将会天差地别!