定义并实现超长整数类double long,要求如下:
64位数据长度,有符号
支持+、-、*、/运算
支持+=、-=、/=运算
支持cin>>和cout<<操作
首先,我们的运算对象是大整数并且要支持cout<<和cin>>操作,数组和链表是可选择项。在这里我们用数组。数组有int型和char型,选哪个好呢?只能选char型,因为我们的大整数是有符号位的,必须用一个char字符来存储。而int型是无法进行存储的。再明确输入的第一个运算数A,输入的第二个运算数B,四则运算后得出的结果是C。
其次,我们的符号在运算的时候不能代入计算,那么我们就要用一个数组K[2]来存储它,将运算数A和B先当成正数来计算(详情见下文),最后根据情况在结果前面添加正负号,听的很迷糊?没关系,看看下面你就知道了:
*,/ 运算时,只需考略A和B的符号,大小不必考虑:
(1).若两运算数的符号相同(即+A,+B或者-A,-B),那么得出的结果也为正的,即+C。
(2).若两两运算数的符号不同(即+A,-B或者-A,+B),那么得出的结果是负的,即-C。
+,- 运算时,既要考虑A和B的正负号,又要考虑大小:
若两运算数的符号同为正(即+A,+B):
(3).加运算直接竖式相加即可。
(4).减运算首先要考虑两数的大小,若A>=B,则直接减运算,若A<B,则进行B-A运算。
若两运算数的符号同为负(即-A,-B):
(5).加运算:(-A)+(-B)=(-C),去掉括号后运算变成(+A)+(+B)=(+C)的运算。最后将结果变成(-C)即可。
(6).减运算就变成了一个正数减去另一个正数的情况,具体见情况(4)。
若两运算数的符号同为负(即+A,-B或者-A,+B):
(7).加运算:将正数放到前面,负数放到后面,加运算就变成了减运算,具体见情况(4)。
(8).减运算第一种情况:(+A)-(-B)。去掉括号(-B)就变成了(+B),这就成了加运算,具体见情况(3)。
(9).减运算第二种情况:(-A)-(+B)。去掉括号后推导出-[(+A)+(+B)]运算,具体见情况(5)。
运算数全为正数时的四则运算:
加法:从低位到高位依次进行竖式相加运算,低位的数分别为m,n,借位初始化为零;若相加的结果k(m+n)超过十,那么向前一位进(k-10)位,借位即(k-10)。将当最后一位(即最高位)算完时,若还是超过十,则不要忘了为进位分配一个存储空间。要注意:须判断出运算数A和B的长度作为循环的基础。
减法:从低位到高位依次进行竖式相减运算,低位的数分别为m,n,借位初始化为零;若减的结果k(m-n)小于零,那么就必须向前面相邻的高位借一位,
同时下一次运算时记住借位的高位要减一位。减运算也要控制好循环条件,否则当A<B, (A-B)<0时,输出的结果会出现未知0.
乘法:乘法也是从低位到高位依次竖式相乘,低位m1,n1相乘,记录结果,并且左移一位,以此类推,直到计算完最后一位,再将各项结果相加。得出最后结果。
除法:除法是从高位向低位依次减,减时以被除数长度为单位,从高位取出大于被除数的字符串,和被除数相减,减的次数为结果,余数从剩下的除数高位再取出几位做补位,直到大于被除数。再减,循环减到被减数大于余数加上补位,那么这个新的余数作为结果返回。
博主的代码如下:
(太烂不敢露脸,,,*-*)
这是我朋友的朋友的一篇代码,写的很好(著作权归原作者所有)。(侵删)
/* 大数运算 */ #include <iostream> #include <string> #include <string.h> #include <stdio.h> using namespace std; const int maxn = 1000; // 最大运算位数 int max(int a, int b) { return a > b ? a : b; } struct bign { int len, s[maxn]; //len记录数字的位数,s存储数字s[0],s[1],s[2]。分别是个位十位百位(以此类推) bign() { memset(s, 0, sizeof(s)); len = 1; } bign operator=(const char * num) //将字符串赋值给大数类型 { len = strlen(num); for (int i = 0; i < len; i++) s[i] = num[len - i - 1] - '0'; int i = len - 1; while (i > 0 && s[i] == 0) i--; // 验证数字的真正大小,避免“0000010”的这样情况 len = i + 1; return *this; } bign operator=(int num) //将int类型赋值给大数类型 { char s[maxn]; sprintf(s, "%d", num); *this = s; return *this; } bign operator=(const bign & b) //大数类型的互相赋值 { len = b.len; for (int i = 0; i < len; i++) s[i] = b.s[i]; return *this; } bign(int num) { *this = num; } //将int转换为大数类型 bign(const char * num) { *this = num; } //同上 string str() const //将大数类型(副本)转换为string { string res = ""; for (int i = 0; i < len; i++) res = (char)(s[i] + '0') + res; if (res == "") res == "0"; return res; } bign operator+(const bign & b) const { bign c; c.len = 0; for (int i = 0, g = 0; g || i < max(len, b.len); i++) { int x = g; if (i < len) x += s[i]; if (i < b.len) x += b.s[i]; c.s[c.len++] = x % 10; g = x / 10; } return c; } bign operator-(const bign & b) const { bign c; bign temp; temp = *this; c.len = 0; for (int i = 0; i < max(temp.len, b.len); i++) { int x = 0; if (i < temp.len) x += temp.s[i]; if (i < b.len) x -= b.s[i]; if (x >= 0) c.s[c.len++] = x; else { c.s[c.len++] = x + 10; temp.s[i + 1]--; } } int i = c.len - 1; while (i > 0 && c.s[i] == 0) i--; //确定数字的真正位数 c.len = i + 1; return c; } bign operator*(const bign & b) const { bign c; for (int i = 0; i < len; i++) { for (int j = 0; j < b.len; j++) { c.s[i + j] += s[i] * b.s[j]; } } for (int i = 0; i < len + b.len - 1; i++) { c.s[i + 1] += c.s[i] / 10; c.s[i] = c.s[i] % 10; } for (int i = len + b.len + 2; i > 0; i--) if (c.s[i] != 0) { c.len = i + 1; break; } return c; } //定义逻辑运算符 bool operator<(const bign & b) const { if (len != b.len) return len < b.len; for (int i = len; i > 0; i--) if (s[i] != b.s[i]) return s[i] < b.s[i]; } bool operator>(const bign & b) const { return b < *this; } bool operator<=(const bign & b) const { return !(b < *this); } bool operator>=(const bign & b) const { return !(*this < b); } bool operator==(const bign & b) const { if (*this < b) return false; else if (*this > b) return false; else return true; } bool operator!=(const bign & b) const { return !(*this == b); } //除法(整除) bign operator/(const bign & b) const { bign temp, result; temp = *this; result = 0; while (temp > b) { temp = temp - b; result = result + 1; } return result; } //取余数 bign operator%(const bign & b) const { bign result; result = *this; while (result > b) result = result - b; return result; } }; istream & operator>>(istream & in, bign & x) { string s; in >> s; x = s.c_str(); return in; } ostream & operator<<(ostream & out, const bign & x) { out << x.str(); return out; } int main() { bign a, b, c; cin >> a >> b; cout << a + b << endl; cout << a * b << endl; cout << a - b << endl; cout << a / b << endl; cout << a % b << endl; return 0; }