Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用BigInteger类在Java中实现无符号64位int?_Java_Types - Fatal编程技术网

如何使用BigInteger类在Java中实现无符号64位int?

如何使用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

我正在寻找一种精确容量为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:某人发布的问题没有实现细节。

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在他的回答和评论中所说的话。