如何使用BigInteger类在Java中实现无符号64位int?
我正在寻找一种精确容量为0到2^64-1的数据类型。我们知道Java目前不支持“unsigned”限制char数据类型 有一个BigInteger类允许创建长数据类型无法支持的较大数字。但我不确定BigInteger类将如何满足我的目的。BigInteger类只允许通过构造函数进行赋值。我看到了以下可能性,但它会生成一个随机数如何使用BigInteger类在Java中实现无符号64位int?,java,types,Java,Types,我正在寻找一种精确容量为0到2^64-1的数据类型。我们知道Java目前不支持“unsigned”限制char数据类型 有一个BigInteger类允许创建长数据类型无法支持的较大数字。但我不确定BigInteger类将如何满足我的目的。BigInteger类只允许通过构造函数进行赋值。我看到了以下可能性,但它会生成一个随机数 BigInteger(int numBits, Random rnd) Constructs a randomly generated BigInteger, unif
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:某人发布的问题没有实现细节。s是不可变的,正如您所发现的。您可能希望研究BigInteger的子类化,并编写自己的构造函数来验证输入,并在相关范围内发出一个正的BigInteger
要保持数字仅使用64位的要求,您可能还需要重载各种操作,以便它们限制结果并返回新类的实例,而不是新的BigInteger
这可能是一项相当大的工作,但仍然比从头开始做要好得多。您可以使用biginger.valueOf(l)从long创建biginger,其中l是long
但是,如果您想使用精确的64位,我会使用long。为什么不编写自己的包装,并在下面使用带符号的long呢。如果用户希望获取作为BigInteger的无符号值-测试符号并将2^64添加到BigInteger。您可能希望创建一个封装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));
}
....
}
您经常可以使用Java的有符号数字数据类型,就好像它们是无符号的一样
关于Java中的有符号与无符号,请参见此部分。您可以在长值中存储值0到2^64-1 许多操作按预期工作,但大多数API和一些操作仅在假定已签名操作时工作,但存在变通方法
不过,使用BigInteger可能会更容易理解 在Java SE 8及更高版本中,您可以使用long数据类型来表示无符号的64位long,其最小值为0,最大值为2^64-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);
}
}
公共静态BigInteger bigIntegerFromUInt64(长uint64){
如果(uint64<0){
ByteBuffer buffer=ByteBuffer.allocate(Long.BYTES);
buffer.putLong(uint64);
字节[]uint64Bytes=buffer.array();
返回新的BigInteger(/*signum*/1,uint64字节);
}否则{
返回BigInteger.valueOf(uint64);
}
}
能否请您明确说明为什么需要该数据类型,以及您正在尝试如何使用该数据类型?有可能简化问题的方法…C++支持这样的数据类型。我与C++交互,认为在java端有一个类似的数据类型,而不是必须操作数据并在C++端转换它,这是更好的。对于另一种方法EE,我的答案是:长支持- 2 ^ 63到(2 ^ 63)-1,第一位是符号位。我想要无符号的long,它的范围是0到(2^64)-1。我想要的不是2^(64-1)。它是(2^64)-1.我相信区别取决于你。如果使用+、-、^、&、|、>,~您会发现结果无法区分。如果你调用Long.toHexString(Long),它不会打印负数。在这个答案中添加一个代码示例或一些文档的链接将非常有用。-请注意新函数<代码>比较签名等。。。这也暗示了Peter Lawrey在他的回答和评论中所说的话。