网站设计 广州,太原广告设计公司,wordpress登录空白,宝安高端网站建设哪家公司好目录 负数二进制表示Java中32位无符号数的取法项目踩坑记录Java 0xffffffff隐式类型转换的坑 负数二进制表示
由于计算机中数据都以二进制表示#xff0c;而负数的二级制是根据正数二进制取补码#xff08;补码就是先取反码#xff0c;然后加1#xff09;得到#xff0c;… 目录 负数二进制表示Java中32位无符号数的取法项目踩坑记录Java 0xffffffff隐式类型转换的坑 负数二进制表示
由于计算机中数据都以二进制表示而负数的二级制是根据正数二进制取补码补码就是先取反码然后加1得到如
一个int 类型的数值为5其长度为32位二进制表示为
00000000 00000000 00000000 00000101
-5是根据5的二进制表示每一位先取反码0变11变0得到
11111111 11111111 11111111 11111010
再对反码加1得到-5的二进制表示
11111111 11111111 11111111 11111011
2、Integer.MAX_VALUE1 Integer.MIN_VALUE 与 Integer.MIN_VALUE-1 Integer.MAX_VALUE
Integer.MAX_VALUE: 01111111 11111111 11111111 111111111: 00000000 00000000 00000000 00000001相加: 10000000 00000000 00000000 00000000
Integer.MIN_VALUE: 10000000 00000000 00000000 00000000
可以看出 Integer.MAX_VALUE1 结果等于 Integer.MIN_VALUEInteger.MIN_VALUE: 10000000 00000000 00000000 00000000-1: 11111111 11111111 11111111 11111111相加: 1 01111111 11111111 11111111 11111111
Integer.MAX_VALUE: 01111111 11111111 11111111 11111111
可以看出Integer.MIN_VALUE1结果将多余位舍去即等于 Integer.MAX_VALUEhttps://blog.csdn.net/weixin_39469127/article/details/98526363
Java中32位无符号数的取法
使用 long 型的 64 位十六进制数 0xFFFFFFFFL对取得的 32 位(4字节)的整型数值做按位与()操作并以 long 型保存这个无符号数值如下long vUnsigned bf.getInt() 0xFFFFFFFFL;注0xFFFFFFFFL 的高32位默认补0末尾的 L 代表 long 型。注事实上Java的 Integer 中已经实现此方法/*** Converts the argument to a {code long} by an unsigned* conversion. In an unsigned conversion to a {code long}, the* high-order 32 bits of the {code long} are zero and the* low-order 32 bits are equal to the bits of the integer* argument.** Consequently, zero and positive {code int} values are mapped* to a numerically equal {code long} value and negative {code* int} values are mapped to a {code long} value equal to the* input plus 2sup32/sup.** param x the value to convert to an unsigned {code long}* return the argument converted to {code long} by an unsigned* conversion* since 1.8*/public static long toUnsignedLong(int x) {return ((long) x) 0xffffffffL;}项目踩坑记录
Agora SDK 对于 UID 的定义如下 JoinChannel 但是在回调中发现UID 为一个负数与描述该参数为 32 位无符号整数不符这是为什么呢 原因
SDK 的 建议 uid 范围0-232 -1超过了 Java int 的范围 -231 – 231 -1所以3944526469 用 -350440827 表示了
解决方案 如果想UID不出现负值可以用得到的UID 做如下运算 UID0xFFFFFFFFL 拿到原始UID
System.out.println(-350440827 0xFFFFFFFFL); //3944526469//System.out.println(2337050656 0xFFFFFFFFL); // error integer number too large
System.out.println((3944526469L 0xFFFFFFFFL)); //-350440827
System.out.println(-350440827 0xFFFFFFFFL); //3944526469查看 Agora 源码 发现也是用这种方法做的
Java 0xffffffff隐式类型转换的坑
longint最终会将int类型隐式转换成long类型而0xffffffff的值为-1java是使用补码存储数值的在隐式类型转换过程中扩展为long类型-10xffffffffffffffff并不是0x00000000ffffffff。
所以需要将0xffffffff写为0xffffffffL(long类型)这样才能避免隐式转换带来错误的结果。
public static void main(String[] args){long ipLong 0x457145130A1901F6L;String ip longToIp(ipLong0xffffffffL);//取低32位L表示long类型System.out.println(ipLong);System.out.println(ip);
}public static String longToIp(long longIP){StringBuffer sbnew StringBuffer();//直接右移24位sb.append(String.valueOf(longIP24));sb.append(.);//将高8位置0然后右移16位sb.append(String.valueOf((longIP0x00FFFFFF)16));sb.append(.);sb.append(String.valueOf((longIP0x0000FFFF)8));sb.append(.);sb.append(String.valueOf(longIP0x000000FF));return sb.toString();
}
补充整数默认int类型在bigsmall表达式中small为(byte)0xff、(short)0xffff、(int)0xffffffff 的-1隐式转换都会出现此类问题
参考链接
https://blog.csdn.net/moakun/article/details/85725236https://blog.csdn.net/weixin_39469127/article/details/98526363https://blog.csdn.net/weixin_43849277/article/details/108530201https://docs-legacy.agora.io/cn/extension_customer/API%20Reference/java_ng/API/toc_core_method.html?platformAndroid#api_irtcengine_joinchannel2