符号运算符号大整数

时间:2015-08-30 14:52:44

标签: delphi bit-manipulation

我在Delphi中编写一个简单的BigInteger类型。此类型由无符号32位整数数组(我称之为四肢),计数(或大小)和符号位组成。数组中的值被解释为绝对值,因此这是符号幅度表示。这有几个优点,但有一个缺点。

andorxornot等按位运算具有两个补码语义。如果两个BigInteger都具有正值,则这是没有问题的,但是负BigInteger s的大小必须通过否定转换为2的补码。这可能是一个性能问题,因为如果我们这样做,请说

C := -A and -B;

然后我必须在执行A操作之前否定Band的大小。由于结果也应该是否定的,我必须否定结果,以便再次获得正数。对于较大的BigInteger s,否定最多三个值可能会产生相当大的性能成本。

请注意,我知道如何做到这一点并且结果是正确的,但我想避免因大型数组的必要否定而导致的缓慢。

我知道一些快捷方式,例如

C := not A;

可以通过计算来实现

C := -1 - A;

这就是我所做的,结果很好。这使得not与加法或减法一样高效,因为它避免了操作之前(和之后)的否定。

问题

我的问题是:是否有类似的法律我可以用来避免否定"否定" BigInteger S'我的意思是使用减法计算not

我的意思是简单或不那么简单的法律,如

not A and not B = not (A or B) // = is Pascal for ==
not A or not B = not (A and B)

但接着是-A和/或-B等我知道

(-A and -B) <> -(A or B) // <> is Pascal for !=

不是真的 ,但也许有类似的东西?

我根本无法找到与值和按位运算相关的任何此类法则(如果它们存在的话)。因此,我的问题。

2 个答案:

答案 0 :(得分:5)

上次我检查否定是这样的:

-A = not(A) + 1; or
-A = not(A - 1);
that means that
-A and -B = not(A - 1) and not(B - 1)

如果我们在前面添加另一个NOT而不是我们可以替换and not    使用or

not(-A and -B) = not(not(A - 1) and not(B - 1)) =
(A - 1) or (B - 1)   

我们仍然需要在最后做一个昂贵的not,但因为不是那么接近-我们可以欺骗并用便宜的{{1}替换昂贵的not像这样:

-

最后结果将是:

-(-A and -B) = (A-1) or (B-1) + 1;

这应该比翻转所有位快得多。

实施起来非常便宜,因为:

  1. 否定是一个简单的位翻转你的符号字节。
  2. 在过度使用的情况下,
  3. + 1 / -1将很快耗尽进位/借位(仅有1/2 ^ 32个案例将进行/借入下一个分支)。
  4. 同样适用于(-A and -B) = -((A-1) or (B-1) + 1); ; or非常接近not or

答案 1 :(得分:1)

  

我的问题是:是否有类似的法律我可以用来避免否定   &#34;负面&#34; BigIntegers?

是的,我之前做过你想做的事 - 请参阅here,第105 - 115行(或更好地下载存储库)。奇怪的是我还使用了术语&#39; Limb&#34;。

例如,arrAndTwoCompl计算正面和负面的按位andarrAndTwoCompl2计算2个底片的按位and

我已经采取了这些法律&#39;来自GMP来源。

不要重新发明大整数,只需使用它们。