有一种简单快捷的方法将Java签名的long转换为无符号的长字符串吗?
-1 -> "18446744073709551615"
-9223372036854775808 -> "09223372036854775808"
9223372036854775807 -> "09223372036854775807"
0 -> "00000000000000000000"
发布于 2018-01-30 10:09:05
下面是使用BigInteger的解决方案:
/** the constant 2^64 */
private static final BigInteger TWO_64 = BigInteger.ONE.shiftLeft(64);
public String asUnsignedDecimalString(long l) {
BigInteger b = BigInteger.valueOf(l);
if(b.signum() < 0) {
b = b.add(TWO_64);
}
return b.toString();
}
这是因为一个(有符号的)数字的无符号值在两-s补码中仅比有符号值多2(位数),而Java的long
有64位
BigInteger有这么好的toString()
方法,我们可以在这里使用。
发布于 2018-01-30 12:00:29
我想出了一个:
public static String convert(long x) {
return new BigInteger(1, new byte[] { (byte) (x >> 56),
(byte) (x >> 48), (byte) (x >> 40), (byte) (x >> 32),
(byte) (x >> 24), (byte) (x >> 16), (byte) (x >> 8),
(byte) (x >> 0) }).toString();
}
使用new BigInteger(int signum, byte[] bytes);
使BigInteger将字节读入正数(无符号)并应用Signum。
我找到了这个:
private static DecimalFormat zero = new DecimalFormat("0000000000000000000");
public static String convert(long x) {
if (x >= 0) // this is positive
return "0" + zero.format(x);
// unsigned value + Long.MAX_VALUE + 1
x &= Long.MAX_VALUE;
long low = x % 10 + Long.MAX_VALUE % 10 + 1;
long high = x / 10 + Long.MAX_VALUE / 10 + low / 10;
return zero.format(high) + low % 10;
}
还有另一种方法:
private static DecimalFormat zero19 = new DecimalFormat("0000000000000000000");
public static String convert(long x) {
if (x >= 0) {
return "0" + zero19.format(x);
} else if (x >= -8446744073709551616L) {
// if: x + 18446744073709551616 >= 10000000000000000000
// then: x + 18446744073709551616 = "1" + (x + 8446744073709551616)
return "1" + zero19.format(x + 8446744073709551616L);
} else {
// if: x + 18446744073709551616 < 10000000000000000000
// then: x + 18446744073709551616 = "09" + (x + 9446744073709551616)
// so: 9446744073709551616 == -9000000000000000000L
return "09" + (x - 9000000000000000000L);
}
}
https://stackoverflow.com/questions/-100005237
复制相似问题