C中的大数减法

大约20分钟前,我刚刚在一门介绍性的C课程中完成了考试。 关于考试的第一个问题让我措手不及,并且找到了两个大数字的差异。

目标是按值获取两个结构(N1和N2),并将差异存储在通过引用传递的结构中(N3)。 我们被允许假设N3是以所有’0’开始的。 MAX大小可以是任何值,因此如果数字超过100位,解决方案仍然有效。

这是基本代码(原始可能略有不同,这是来自内存)

#include  #include  /* MAX can be any length, 10, 50, 100, etc */ #define MAX 10 struct bignum { char digit[MAX]; char decimaldigit[MAX/2]; }; typedef struct bignum bigNum; void difference(bigNum, bigNum, bigNum *); /* Original values in N1 and N2 N1.digit = { '0', '0', '0', '5', '4', '8', '2', '0', '9', '0'}; N1.decimaldigit { '0', '0', '0', '4', '9' }; N2.digit = { '0', '0', '0', '4', '8', '1', '3', '1', '4', '5'}; N2.decimaldigit { '8', '0', '1', '2', '0' }; */ /* Result would be: N3.digit = { '0', '0', '0', '0', '6', '6', '8', '9', '4', '4'} N3.decimaldigit { '1', '9', '9', '2', '9' } */ 

问题不在于找到解决这个问题的方法,而是为完整答案提供了大约约20行。 我的解决方法包括在转换为整数后一次减去一个数字,然后如果结果为负则进行适当的携带。 这比所提供的空间大得多。

基于少量的标记和为这个问题提供的空间,我会相信有一个相当简单的解决方案,我没有看到。 它是什么? 我现在已经完成了课程,但这个问题仍困扰着我!

不需要完整的解决方案,只需要functiondifference的内部工作原理。

为了以防万一,不使用按位运算符。

如果N1 >= N2这应该有效。 这也假设数组的布局类似于dn...d2d1d0.e0e1...em

 char digchr(int); // Converts a single-digit integer into a character. void difference(bigNum N1, bigNum N2, bigNum *N3) { int carry = 0; for (int i = MAX / 2 - 1; i >= 0; i--) { int diff = N1.decimalDigits[i] - N2.decimalDigits[i] - carry; if (diff < 0) { diff += 10; carry = 1; } else { carry = 0; } N3->decimalDigits[i] = digchr(diff); } for (int i = 0; i < MAX; i++) { int diff = N1.digits[i] - N2.digits[i] - carry; if (diff < 0) { diff += 10; carry = 1; } else { carry = 0; } N3->digits[i] = digchr(diff); } } 

大多数计算机科学课程中的BigNumber问题旨在使您必须按照您的描述“手动”进行算术运算:将每个字符转换为整数,减去并在适当时借用。

正如您所描述的那样,您的计划攻击应该只有几行。 在伪代码中,类似这样的东西:

 for each character (right to left): difference = N1.digit[i] - N2.digit[i]; if (difference < 0) N1.digit[i - 1]--; difference += 10; N3.digit[i] = difference; 

(另外一点麻烦就是将相同的逻辑应用于十进制数字。)

听起来你有正确的想法,也许只是过度思考实施?

亲爱的教授,减法应该根据加法来定义。 我已经重载了一元“ – ”运算符并在别处定义了bignum添加例程。 我正在使用9的补码来简化/加速添加(不需要讨厌的进位!)和基于表的回答查找(为什么只有10个时才计算总和?)。 bigNum减法例程(根据您的规范)如下:

 void bigDifference(bigNum N1, bigNum N2, bigNum *N3) { bigSum(N1, -N2, N3); }