所以我试图编写代码以减去两个二进制数,但是我不确定如何优雅地解决此问题。保留二进制数的结构如下。
typedef struct _bitb {
short bit;
struct _bitb *nbit;
} BitB;
typedef struct _bignum {
short sign;
BitB *bits;
} BigNum;
因此,一个二进制数由一个包含其绝对值的位的列表(从LSB到MSB)表示,然后用一个简短的数字表示该数字是正数还是负数(这是一种任意精度算法的实现)。如何在不带补码的情况下从另一个中减去一个数?
在有人问之前,这是上学的时间,但是我不想要代码中的解决方案,而只是可以实现的通用算法。我一直在搜索,似乎没有一种可以解决一般情况的好的算法。我是否需要检查数字的符号,然后针对所有可能的情况(负负正数,正负负数,正负正数,负负正数)实施代码?还是我应该转换为2的补码?
答案 0 :(得分:4)
这是上学的时间,但是我不想要代码中的解决方案,而只是可以实现的通用算法
BigNum
是整数的符号幅度链接列表编码。
要添加/减去BigNum
,需要编写代码以添加/减去每个BitB
操作数的大小。
要增加幅度,可以很容易地遍历BitB
链表并随手形成和。
// pseudo-code
BitB *BitBAdd(const BitB *a, const BitB *b) {
BitB temp_head = set next member to NULL
BitB *bit_walker = pointer to the head
bool carry = false;
while (a is not end of list, b not end of list, or carry) {
bool abit = get bit from a if not NULL and advance a, else 0
bool bbit = get bit from b if not NULL and advance b, else 0
bit_walker->nbit = malloc(sizeof *(bit_walker->nbit));
check allocation success
advance bit_walker
set bit_walker->nbit members to NULL, abit ^ bbit ^ carry
carry = majority(abit, bbit, carry);
}
return temp_head.nbit;
}
幅度的减法要求首先找到一个大的int BitBCmp(const BitB *a, const BitB *b)
。代码未显示。减法函数BitB *BitBCmp(const BitB *larger, const BitB *smaller)
类似于BitBAdd()
。未显示。
一旦制作了BitBAdd()
,BitBCmp()
和BitBSub()
,然后可以通过检查符号并调用各种{{1}来制作BigNum_Add()
和BigNum_Sub()
},如@user3386109所建议。
侧面问题
BitB...()
约占完成OP任务所需代码的20-25%。
可能需要将最高有效的零位数字掉下来。还应考虑符号幅度编码可以生成+0和-0。
答案 1 :(得分:2)
您可以将问题减少为两种情况:符号相反和符号相同。
减去具有相反符号的数字需要将两个绝对值相加。例子:
(-7) - (+5) = -(7+5)
(+7) - (-5) = +(7+5)
要减去具有相同符号的数字,需要从较大的绝对值中减去较小的绝对值。例子:
(+7) - (+5) = +(7-5)
(+7) - (+9) = -(9-7)
(-7) - (-5) = -(7-5)
(-7) - (-9) = +(9-7)
如您所见,结果的符号实际上有6种情况,如下所示(其中X,Y和Z是数字的大小)。
(-X) - (+Y) ==> -(Z)
(+X) - (-Y) ==> +(Z)
(+X) - (+Y) and (X >= Y) ==> +(Z)
(+X) - (+Y) and (X < Y) ==> -(Z)
(-X) - (-Y) and (X > Y) ==> -(Z)
(-X) - (-Y) and (X <= Y) ==> +(Z)
总结:
如果两个数字的符号相反,则将其大小相加。
如果两个数字具有相同的符号,则从较大的幅度中减去较小的幅度。
然后确定结果的符号。
答案 2 :(得分:0)
对于A-B
,其中|A| < |B|
,您需要2的补全。例如如果A = 2
和B = 5
,A-B
将是-3
,则必须取结果的2的补码。 -(5-3)
。在任何情况下,您都必须使用2的补码。
我建议您使用2的补码将减法转换为加法。
即如果您有ans = A-B
,则取B
的2的补码,然后加。
然后您将获得ans = A + (-B)
。
第1步。取B的2的补码
步骤2。将A加上2的补码。
这将在很大程度上简化代码。
这也是在CPU内部处理数字减法的方法。