Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.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
Java 如何转换一个";“未签名”;长到大整数_Java_Long Integer_Biginteger - Fatal编程技术网

Java 如何转换一个";“未签名”;长到大整数

Java 如何转换一个";“未签名”;长到大整数,java,long-integer,biginteger,Java,Long Integer,Biginteger,如果我有一个Javalong值,比如说x,它应该被解释为无符号值(即0x8000_0000_0000_0000和更高的值应该被解释为正值),那么我如何将它转换为biginger 显然,biginger.valueOf(x)将导致负值,转换为十六进制或字节似乎是浪费。实际上,转换非常简单。可以使用类似于将无符号整数转换为长整数的掩码: 让我们首先将掩码创建为常量(这只会将最低有效32位设置为1): 因此,对于biginger我们可以创建如下掩码(64个最低有效位设置为1): 太好了,那么剩下的

如果我有一个Java
long
值,比如说
x
,它应该被解释为无符号值(即
0x8000_0000_0000_0000
和更高的值应该被解释为正值),那么我如何将它转换为
biginger


显然,
biginger.valueOf(x)
将导致负值,转换为十六进制或字节似乎是浪费。

实际上,转换非常简单。可以使用类似于将无符号整数转换为长整数的掩码:


让我们首先将掩码创建为常量(这只会将最低有效32位设置为1):


因此,对于
biginger
我们可以创建如下掩码(64个最低有效位设置为1):

太好了,那么剩下的就简单了:

long unsignedLong = 0x8000_0000_0000_0000L; // sample input value
BigInteger bi =  BigInteger.valueOf(unsignedLong).and(UNSIGNED_LONG_MASK);


这不是火箭科学,但有时你只是想找到一个简单快捷的答案。

这个转换实际上是在OpenJDK的
java.lang.Long
中实现的。但它是私人的,所以将其粘贴到此处:

/**
 * Return a BigInteger equal to the unsigned value of the
 * argument.
 */
private static BigInteger toUnsignedBigInteger(long i) {
    if (i >= 0L)
        return BigInteger.valueOf(i);
    else {
        int upper = (int) (i >>> 32);
        int lower = (int) i;

        // return (upper << 32) + lower
        return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
            add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
    }
}
/**
*返回一个BigInteger,该值等于
*争论。
*/
私有静态BigInteger toUnsignedBigInteger(长i){
如果(i>=0L)
返回BigInteger.valueOf(i);
否则{
整数上限=(整数)(i>>>32);
整数下限=(整数)i;

//return(在我的机器上,使用长到字节数组的转换速度快了6倍这是一个真正的魔法(intrinsics)继续。我现在会检查哪一个更快。你测试过生成掩码还是不生成掩码吗?我刚刚用你的代码生成了BigInteger。
UNSIGNED_LONG_mask
当然是静态字段,最后两行代码会被测量。还有什么可以改进的?(
unsignedLong
取自
ThreadLocalRandom
,但我认为这无关紧要)在测量中使用随机是相当棘手的-如果它阻止了测量,那么你的测量就关闭了,并且随机生成通常使用一个繁重的加密算法。然后在JIT编译开始之前有JVM时间。最后,你有字节数组的垃圾收集,这可能只有在你执行测试之后才开始…这是主题并不像看上去那么简单。嗯,链接是错误的:
// use "import static java.math.BigInteger.ONE;" to shorten this line
private static final BigInteger UNSIGNED_LONG_MASK = BigInteger.ONE.shiftLeft(Long.SIZE).subtract(BigInteger.ONE);
long unsignedLong = 0x8000_0000_0000_0000L; // sample input value
BigInteger bi =  BigInteger.valueOf(unsignedLong).and(UNSIGNED_LONG_MASK);
/**
 * Return a BigInteger equal to the unsigned value of the
 * argument.
 */
private static BigInteger toUnsignedBigInteger(long i) {
    if (i >= 0L)
        return BigInteger.valueOf(i);
    else {
        int upper = (int) (i >>> 32);
        int lower = (int) i;

        // return (upper << 32) + lower
        return (BigInteger.valueOf(Integer.toUnsignedLong(upper))).shiftLeft(32).
            add(BigInteger.valueOf(Integer.toUnsignedLong(lower)));
    }
}