提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
在蓝桥杯备赛中遇到大数的乘法,兴致一来,构建一个大数类练练手
在学习加法器和乘法器之后,利用相似的原理,利用数组构建了无符号大数类,支持加法和乘法的基本操作。
主要用到运算符重载、输入输出重载的知识。
一、类的头文件Numorous.h
//Numorous.h
#pragma once
#include <iostream>
#define int_dec_length 200
//在这里定义十进制数最大长度
using namespace std;
class Int
{
public:
//各种构造函数
Int();
Int(int arr[],int length);
Int(long long num);
Int(int num);
~Int();
//打印输出大数,统计长度
void show()const;
//单目移位
void operator<<=(int num);
void operator>>=(int num);
//双目移位
Int operator>>(int num);
Int operator<<(int num);
//输入输出重载
friend ostream& operator<< (ostream& out, Int A);
friend istream& operator>> (istream& in, Int& A);
//单目加法
void operator+=(long long num);
void operator+=(int num);
void operator+=(Int B);
//双目加法
Int operator+(long long num);
Int operator+(int num);
Int operator+(Int B);
//单目乘法
void operator*= (long long num);
void operator*=(int num);
void operator*=(Int B);
//双目乘法
Int operator*(long long num);
Int operator*(int num);
Int operator*(Int B);
static Int factor(int num); //静态函数,可以算num的阶乘
private:
int len; //长度
int A[int_dec_length]; //记录数据的数组
};
二、类的实现文件Numorous.cpp
#include "Numorous.h"
Int::Int(){
len = 0;
for (int i = 0; i < int_dec_length; ++i) A[i] = 0;
}
Int::Int(int arr[],int length){
if (length > 0) {
for (int i = 0; i < length; i++) A[length - 1 - i] = arr[i];
len = length;
}
if (len < 0) {
for (int i = 0; i < -length; i++)A[i] = arr[i];
len = -length;
}
for (int i = len; i < int_dec_length; ++i)A[i] = 0;
}
Int::Int(long long num){
int i = 0;
while (num) {
A[i++] = num % 10;
num /= 10;
}
len = i;
for (int i = len; i < int_dec_length; ++i)A[i] = 0;
}
Int::Int(int num){
int i = 0;
while (num) {
A[i++] = num % 10;
num /= 10;
}
len = i;
for (int i = len; i < int_dec_length; ++i)A[i] = 0;
}
Int::~Int(){
}
void Int::show()const{
if (len == 0) { cout << "NULL" << endl; return; }
for (int i = len-1; i >= 0; --i) {
cout << A[i];
}
cout << " "<<"len: " << len << endl;
}
void Int::operator<<=(int num) {
for (int i = int_dec_length - 1; i >= num; --i) {
A[i] = A[i - num];
}
for (int i = 0; i < num; ++i) {
A[i] = 0;
}
len += num;
}
void Int::operator>>=(int num) {
for (int i = 0; i <= int_dec_length - num - 1; ++i) {
A[i] = A[i + num];
}
len -= num;
}
Int Int::operator>>(int num){
Int B = *this;
B >>= num;
return B;
}
Int Int::operator<<(int num){
Int B = *this;
B <<= num;
return B;
}
ostream& operator<< (ostream& out, Int A) {
A.show();
return out;
}
istream& operator>> (istream& in, Int& A) {
long long tmp = 0;
in >> tmp;
A = tmp;
return in;
}
void Int::operator+=(long long num){
long long s = 0, c = num;
for (int i = 0; i < int_dec_length; ++i) {
s = A[i] + c;
A[i] = s % 10;
c = s / 10;
}
for (int i = 0; i < int_dec_length; ++i) {
if (A[i] != 0)len = i + 1;
}
}
void Int::operator+=(int num){
int s = 0, c = num;
for (int i = 0; i < int_dec_length; ++i) {
s = A[i] + c;
A[i] = s % 10;
c = s / 10;
}
for (int i = 0; i < int_dec_length; ++i) {
if (A[i] != 0)len = i + 1;
}
}
void Int::operator+=(Int B){
int s = 0, c = 0;
for (int i = 0; i < int_dec_length; ++i) {
s = A[i] + B.A[i] + c;
A[i] = s % 10;
c = s / 10;
}
for (int i = 0; i < int_dec_length; ++i) {
if (A[i] != 0)len = i + 1;
}
}
Int Int::operator+(long long num){
Int B = Int(A, -len);
B += num;
return B;
}
Int Int::operator+(int num){
Int B = Int(A, -len);
B += num;
return B;
}
Int Int::operator+(Int B){
Int C = B;
C += *this;
return C;
}
void Int::operator*=(long long num){
long long s = 0, c = 0;
for (int i = 0; i < int_dec_length; ++i) {
s = A[i] * num + c;
A[i] = s % 10;
c = s / 10;
}
for (int i = 0; i < int_dec_length; ++i) {
if (A[i] != 0)len = i + 1;
}
}
void Int::operator*=(int num) {
long long s = 0, c = 0;
for (int i = 0; i < int_dec_length; ++i) {
s = A[i] * num + c;
A[i] = s % 10;
c = s / 10;
}
for (int i = 0; i < int_dec_length; ++i) {
if (A[i] != 0)len = i + 1;
}
}
void Int::operator*=(Int B) {
Int C = *this;
*this = 0;
for (int i = B.len - 1; i >= 0; --i) {
this->operator+=(C * B.A[i]);
this->operator<<=(1);
}
this->operator>>=(1);
}
Int Int::operator*(long long num) {
Int C = *this;
C *= num;
return C;
}
Int Int::operator*(int num) {
Int C = *this;
C *= num;
return C;
}
Int Int::operator*(Int B) {
Int C = B;
C *= *this;
return C;
}
Int Int::factor(int num){
Int A = 1;
if (num <= 0) {
cout << "Error!" << endl;
return A;
}
for (int i = 1; i <= num; ++i) {
A *= num;
}
return A;
}
源文件main.cpp内的调用示例
1、整数初始化,乘法,阶乘
Int a = 54321;
Int b = 10000100001;
Int c = a * b;
a.show(); //54321
cout << c; //5432154321
cout << Int::factor(22); //很长的一个30位数字
//341427877364219557396646723584 len:16
2、数组初始化,加法,移位
int arr[16] = { 1,2,3,4,5,6,7,6,5,4,3,2,1,1,1,1 };
Int a(arr, 16); //1234567654321111 len:16
Int b;
cin >> b; //999999 len:6
cout << a << b;
Int c = a + b;
cout << c; //1234567655321110 len:16
c >>= 3;
c.show(); //1234567655321 len: 13
总结
整体逻辑不是很复杂,只要明确A[i]各个位之间的进位关系无脑for循环,个人感觉某些循环设计太冗余,但也想不到更好的方法去解决。
入门小白第一次尝试写博客,如有不足,还请批评指正。