有没有办法正确地左旋(不仅仅是移位)固定大小的BigIntegers?
我尝试编写一种方法,类似于用于旋转整数的经典旋转方法,但它不适用于BigIntegers。它只是将位向左移位r位置,最后填充零。
public static BigInteger rotate(BigInteger n, int r){
return n.shiftLeft(r).or(n.shiftRight(128-r));
}
编辑:不使用BigIntegers并使用long或整数数组看起来像另一个选项,但我不确定你是如何组合它们(除了使用BigIntegers)来执行旋转。
答案 0 :(得分:2)
实际上并不那么容易。旋转点在哪里?这对于固定大小的数字(如32位或64位整数)很容易,但对BigIntegers则不行。
但是......理论上,BigIntegers的大小是无限的,而且是两个补码(或者至少,它们表现得像它们一样,实际上它们通常是符号量级的)。所以正数(实际上)前面是无限数量的0位和负数,其中无限数量的1位。因此向左旋转1实际上意味着向左移动1,如果数字为/是负数,则最低位设置为1.
如果BigInteger仅用于表示固定大小整数(BigIntegers本身没有固定大小),则必须将顶部位移到底部。然后你可以做类似的事情:
public static BigInteger rotateLeft(BigInteger value, int shift, int bitSize)
{
// Note: shift must be positive, if necessary add checks.
BigInteger topBits = value.shiftRight(bitSize - shift);
BigInteger mask = BigInteger.ONE.shiftLeft(bitSize).subtract(BigInteger.ONE);
return value.shiftLeft(shift).or(topBits).and(mask);
}
你称之为:
public static void main(String[] args)
{
BigInteger rotated = rotateLeft(new
BigInteger("1110000100100011010001010110011110001001101010111100110111101111" +
"1111111011011100101110101001100001110110010101000011001000010010",
2), 7, 128);
System.out.println(rotated.toString(2));
}
注意:我测试了这个,它似乎产生了预期的结果:
10010001101000101011001111000100110101011110011011110111111111110110111001011101010011000011101100101010000110010000100101110000
如果bitSize是固定的(例如总是128),你可以预先计算掩码,当然也不必将bitSize传递给函数。
要获得面具,而不是向左移动BigInteger.ONE
,您也可以这样做:
BigInteger.ZERO.setBit(bitSize).subtract(BigInteger.ONE);
这可能会快一点。