我正在寻找一个精确容量为0到2 ^ 64的数据类型 - 1.我们知道Java本身不支持'unsigned'禁止char数据类型。
BigInteger类允许创建长数据类型不支持的更大数字。但我不确定BigInteger课程将如何满足我的目的。 BigInteger类只允许通过构造函数进行赋值。我看到以下可能性,但它会生成一个随机数。
BigInteger(int numBits, Random rnd)
Constructs a randomly generated BigInteger, uniformly distributed over the range 0 to (2^numBits - 1), inclusive.
我看不到任何setValue(x)类型的API,它允许我为这个BigInteger选择我自己的值。如何使用BigInteger类实现这个或者还有其他方法吗?请发布代码示例。
PS:某人here发布的问题没有实施细节。
答案 0 :(得分:6)
您经常可以使用Java的签名数字数据类型,就好像它们是未签名的一样。
请参阅此old answer有关Java中已签名与未签名的内容。
答案 1 :(得分:3)
为什么不编写自己的包装器并在下面使用签名长。如果用户希望以BigInteger的形式获取无符号值 - 测试符号并将2 ^ 64添加到BigInteger。
答案 2 :(得分:2)
您可能想要创建一个封装BigInteger的UInt64类;你还可以检查每个操作(add,mul等)是否返回一个无符号的64位BigInteger;模拟溢出可能很棘手
class UInt64 {
private final BigInteger value;
private UInt64(BigInteger aValue) {
// method to enforce your class invariant: 0...2**64-1
checkInvariantOf(aValue);
value = aValue;
}
public static UInt64 of(String value) {
return new UInt64(new BigInteger(value));
}
public UInt64 add(UInt64 v) {
return new UInt64(value.add(v.value));
}
....
}
答案 3 :(得分:1)
BigInteger是不可改变的。您可能希望查看子类化BigInteger,并编写自己的构造函数来验证输入,并在相关范围内发出正的BigInteger。
为了保持数字仅使用64位的要求,您可能还需要重载各种操作,因此它们会限制结果并返回新类的实例而不是新的BigInteger。
这可能是相当多的工作,但仍然要比从头开始做得好得多。
答案 4 :(得分:1)
您可以使用BigInteger.valueOf(l)从long创建BigInteger,其中l是long。
但是如果你想使用精确的64位,我会使用很长的时间。
答案 5 :(得分:1)
您可以将值0到2 ^ 64-1存储为长值。
许多操作按预期工作,但是大多数API和一些操作仅在它们采用签名操作时起作用,但是有解决方法。
然而,使用BigInteger可能更容易让人头疼。 ;)
答案 6 :(得分:1)
在Java SE 8及更高版本中,您可以使用长数据类型来表示无符号的64位长,其最小值为0,最大值为2 ^ 64-1。
答案 7 :(得分:1)
要将uint64输入到BigInteger
中,可以使用带有字节数组和符号的构造函数:
public static BigInteger bigIntegerFromUInt64(long uint64) {
if (uint64 < 0) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(uint64);
byte[] uint64Bytes = buffer.array();
return new BigInteger(/* signum */ 1, uint64Bytes);
} else {
return BigInteger.valueOf(uint64);
}
}