是否有一种方法可以正确地左转(而不仅仅是移位)固定大小的BigIntegers?
我尝试过编写一种类似于经典旋转方法的方法,该方法用于旋转整数,但它不适用于BigIntegers。它只是用r的位置向左移动,在末尾填充零。
public static BigInteger rotate(BigInteger n, int r){
return n.shiftLeft(r).or(n.shiftRight(128-r));
}编辑:不使用BigIntegers和使用多头或整数数组似乎是另一种选择,但我不知道如何组合它们(除了使用BigIntegers)来执行旋转。
发布于 2017-04-22 22:31:22
其实这并不容易。旋转点在哪里?对于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);那可能要快一点。
https://stackoverflow.com/questions/43561017
复制相似问题