Java中32位二进制补码字符串转primitive long报错问题排查
问题分析与解决方案
你遇到的NumberFormatException主要有两个原因:
- 错误地使用
Long.valueOf(s1)解析二进制字符串——这个方法默认按十进制解析字符串,而s1是二进制格式,直接解析必然报错; - 即便改成
Long.parseLong(s1, 2),该方法会把32位二进制字符串当成有符号数解析,最高位为1时会被识别为负数,不符合你需要的无符号32位值转换需求。
方案一:修正字符串解析逻辑
将二进制字符串按无符号数解析,使用Java 8+提供的Long.parseUnsignedLong()方法,指定基数为2即可正确转换:
public static long flippingBits(long n) { String s = Long.toBinaryString(n); StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.length(); i++) { sb.append(flip(s.charAt(i))); } int b = 32 - s.length(); // 简化长度计算,无需转数组 String s1 = sb.toString(); for (int i = 0; i < b; i++) { s1 = "1" + s1; } // 按无符号二进制解析字符串 long res = Long.parseUnsignedLong(s1, 2); return res; } static char flip(char c) { return (c == '0') ? '1' : '0'; }
方案二:用位运算直接实现(更高效)
你的需求本质是将输入值视为32位无符号数取反,用位运算可以跳过字符串操作,一步完成:
~n对long的所有64位取反,再和0xFFFFFFFFL(低32位全1、高32位全0)做与运算,保留低32位的取反结果,高32位置0,正好符合需求。
public static long flippingBits(long n) { return ~n & 0xFFFFFFFFL; }
测试输入9时,该方法会直接返回4294967286,完全匹配示例预期。
内容的提问来源于stack exchange,提问作者Komal Bhagure
相关产品推荐
相关产品推荐

