我在Delphi中编写了一个简单的BigInteger类型。这种类型包括一个无符号的32位整数数组(我称它们为肢体),一个计数(或大小)和一个符号位。数组中的值被解释为绝对值,因此这是一个符号幅度表示。这有几个优点,但有一个缺点。
andorxornot这样的按位运算具有二进制补码语义。如果两个BigInteger都具有正值,那么这没问题,但是必须通过求反将负BigInteger的幅度转换为二进制补码。这可能是一个性能问题,因为如果这样做,例如

C := -A and -B;
那么我必须先否定AB的大小,然后才能执行and操作。由于结果也应该是负数,因此我也必须取反结果才能再次获得正数。对于较大的BigInteger,最多取三个值将是相当大的性能成本。
提醒您,我知道如何执行此操作,结果是正确的,但是我想避免由于对大型数组进行必要的求反而导致速度变慢。
我知道一些捷径,例如
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 !=
不是真正的,但是也许有类似的东西吗?
我根本找不到与负值和按位运算相关的任何此类定律,如果它们存在的话。因此,我的问题。

最佳答案

上次我检查否定像这样工作:

-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,但是由于距离-不那么近,我们可以作弊并用便宜的not替换昂贵的-,如下所示:
-(-A and -B) = (A-1) or (B-1) + 1;

最后结果将是:
(-A and -B) = -((A-1) or (B-1) + 1);

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

这将实现起来非常便宜,因为:
  • 取反是对您的符号字节的简单翻转。
  • 在过度焊接的情况下,
  • + 1/-1很快会用完随身携带/借用位(只有1/2 ^ 32例将随身携带/借用到下一个肢体)。
  • or也是如此; not or非常接近and

    关于delphi - 符号幅度大整数的按位运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32297820/

    10-14 18:20
    查看更多