我在Delphi中编写了一个简单的BigInteger类型。这种类型包括一个无符号的32位整数数组(我称它们为肢体),一个计数(或大小)和一个符号位。数组中的值被解释为绝对值,因此这是一个符号幅度表示。这有几个优点,但有一个缺点。
像and
,or
,xor
和not
这样的按位运算具有二进制补码语义。如果两个BigInteger
都具有正值,那么这没问题,但是必须通过求反将负BigInteger
的幅度转换为二进制补码。这可能是一个性能问题,因为如果这样做,例如
C := -A and -B;
那么我必须先否定A
和B
的大小,然后才能执行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);
这应该比翻转所有位要快得多。
这将实现起来非常便宜,因为:
or
也是如此; not or
非常接近and
。关于delphi - 符号幅度大整数的按位运算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32297820/