我目前正在尝试解析一些在java中存储为字符串的长值,我遇到的问题是:
String test = "fffff8000261e000"
long number = Long.parseLong(test, 16);
抛出NumberFormatException:
java.lang.NumberFormatException: For input string: "fffff8000261e000"
但是,如果我从字符串中敲出第一个'f',它就可以解析它。
我猜这是因为数字很大而且我通常做的是在长的末尾放一个'L'来解决这个问题。但是,当从字符串解析long时,我无法找到最好的方法。
有人可以提供任何建议吗?
由于
答案 0 :(得分:4)
有两种不同的方式来回答你的问题,具体取决于你真正想要的行为。
答案#1:正如其他人所指出的那样,你的字符串(解释为正十六进制整数)对于Java long
类型来说太大了。因此,如果你真的需要(正)整数那么大,那么你需要使用不同的类型,也许java.math.BigInteger
,它也有一个构造函数取String
和基数。
答案#2:我想知道,如果你的字符串代表long
的“原始”字节。在您的示例中,它将表示负数。如果是这种情况,那么Java的内置long
解析器不会处理设置高位的值(即16位字符串的第一个数字大于7的位置)。
如果你遇到#2,那么这是一种(效率很低)的处理方式:
String test = "fffff8000261e000";
long number = new java.math.BigInteger(test, 16).longValue();
产生值-8796053053440
。 (如果你的字符串长度超过16位十六进制数字,它会默默地丢弃任何更高的位。)
如果效率是一个问题,你可以编写自己的bit-twiddling例程,一次取两个字符串末尾的十六进制数字,可能构建一个字节数组,然后转换为long。这里有一些类似的代码:
答案 1 :(得分:1)
您正在解析的数字太大而无法容纳在Java Long中。添加L
无济于事。如果Long是一个无符号数据类型,它就适合。
应对的一种方法是将字符串分成两部分,然后在将它们组合在一起时使用位移:
String s= "fffff8000261e000";
long number;
long n1, n2;
if (s.length() < 16) {
number = Long.parseLong(s, 16);
}
else {
String s1 = s.substring(0, 1);
String s2 = s.substring(1, s.length());
n1=Long.parseLong(s1, 16) << (4 * s2.length());
n2= Long.parseLong(s2, 16);
number = (Long.parseLong(s1, 16) << (4 * s2.length())) + Long.parseLong(s2, 16);
System.out.println( Long.toHexString(n1));
System.out.println( Long.toHexString(n2));
System.out.println( Long.toHexString(number));
}
注意:
如果数字大于Long.MAX_VALUE,则生成的long
将为负值,但位模式将与输入匹配。
答案 2 :(得分:1)
原始long变量可以保存从-9,223,372,036,854,775,808
到9,223,372,036,854,775,807
的范围内的值。
计算显示fffff8000261e000
十六进制为18,446,735,277,656,498,176
十进制,显然超出界限。相反,fffff8000261e000
十六进制是1,152,912,708,553,793,536
十进制,显然在界限范围内。
正如大家在此提议的那样,使用BigInteger
来解释此类案件。例如,BigInteger bi = new BigInteger("fffff8000261e000", 16);
将解决您的问题。此外,new java.math.BigInteger("fffff8000261e000", 16).toString()
将完全产生18446735277656498176
。