1. 程式人生 > >高精度加法和乘法的c++實現

高精度加法和乘法的c++實現

上一篇用c寫了高精度加法的計算,總的來說,從底層寫起的話,對於不是很繁瑣的程式碼,面向過程還是比較方便的。但是當我打算計算高精度乘法的時候,發現計算過程要比加法麻煩的多,而且會反覆用到一些函式的呼叫,而且這裡面還會用到高精度加法的計算,於是果斷放棄的c,採用c++。

這裡,我寫了一個類,名為megaData,就是指一個很大的數(不過這個單詞好像是指大資料,完全不懂大資料是什麼,反正就這麼命名了)。

類檢視如下:


.h檔案:

#pragma once
#include<iostream>
#include<time.h>

using namespace std;

//資料倒序儲存(輸出的時候反序)
class megaData
{
private:
	int * pmegaData;//指向資料的指標

	int length;//資料長度

	megaData operator*(int a);//"*"的過載(a是個位數)
	megaData extend(int Len, int move, megaData &a);
public:
	megaData();
	megaData(int length);
	megaData(megaData&a);//拷貝構造

	megaData operator=(megaData&a);//"="的過載

	megaData operator+(megaData&a);//"+"的過載

	megaData operator*(megaData&a);//"*"的過載

	void print();//列印資料

	void printLenth();//列印資料長度

	~megaData();
};


.cpp檔案:

#include "megaData.h"

megaData::megaData()
{
	srand((unsigned)time(NULL));

	pmegaData = new int[100];

	for (int i = 0; i < 100; ++i) {
		pmegaData[i] = rand() % 10;
	}

	this->length = 100;
}

megaData::megaData(int length)
{

	pmegaData = new int[length];

	for (int i = 0; i < length; ++i) {
		pmegaData[i] = rand() % 10;
	}

	this->length = length;
}

megaData::megaData(megaData & a)
{
	pmegaData = new int[a.length];

	length = a.length;

	memcpy(pmegaData, a.pmegaData, sizeof(int)*length);
}

//"="的過載
megaData megaData::operator=(megaData & a)
{
	delete(this->pmegaData);

	this->pmegaData = new int[a.length];

	this->length = a.length;

	for (int i = 0; i < a.length; ++i) {

		this->pmegaData[i] = a.pmegaData[i];
	}

	return *this;
}


//"+"的過載
megaData megaData::operator+(megaData &a)
{
	int lenth_result;//結果的長度(開頭可能會是0)

	if (this->length > a.length) lenth_result = this->length + 1;
	else lenth_result = a.length + 1;//通過一個判斷來確定結果的長度


	int * a2 = new int[lenth_result];//a2***********

	int * b2 = new int[lenth_result];//b2***********

	memcpy(a2, a.pmegaData, sizeof(int)*a.length);

	memset(a2 + a.length, 0, sizeof(int)*(lenth_result - a.length));

	memcpy(b2, this->pmegaData, sizeof(int)*this->length);

	memset(b2 + this->length, 0, sizeof(int)*(lenth_result - this->length));


	int * result = new int[lenth_result];//result*********


	result[0] = a2[0] + b2[0];

	for (int i = 1; i < lenth_result - 1; ++i) {

		result[i] = a2[i] + b2[i] + result[i - 1] / 10;

		result[i - 1] = result[i - 1] % 10;
	}

	result[lenth_result - 1] = result[lenth_result - 2] / 10;

	result[lenth_result - 2] = result[lenth_result - 2] % 10;

	delete[] a2;
	delete[] b2;

	megaData result2(lenth_result);

	if (result[lenth_result - 1] == 0) {//如果結果的最大位是0(說明多了一位)

		delete[] result2.pmegaData;

		result2.pmegaData = new int[lenth_result - 1];

		memcpy(result2.pmegaData, result, sizeof(int)*(lenth_result - 1));

		result2.length = lenth_result - 1;
	}
	else {
		memcpy(result2.pmegaData, result, sizeof(int)*(lenth_result));
	}
	return result2;
}

//"*"的過載
megaData megaData::operator*(megaData & a){

	int Len = this->length + a.length;
	
	megaData result = *this * a.pmegaData[a.length-1];

	result = extend(Len, a.length - 1, result);

	for (int i = a.length - 2; i >= 0; --i) {

		megaData tempresult = *this * a.pmegaData[i];

		tempresult = extend(Len, i, tempresult);

		result = tempresult + result;
	}

	if (result.pmegaData[result.length] == 0) {//如果結果的最大位是0(說明多了一位)
		result.length -= 1;
	}

	return result;
}


//"*"的過載(a是個位數)
megaData megaData::operator*(int a)
{
	megaData result(this->length + 1);

	for (int j = 0; j < length + 1; ++j) {

		if (j == 0) {//第一位

			result.pmegaData[j] = a*this->pmegaData[j] % 10;

		}
		else if (j == length ) {//最後一位

			result.pmegaData[j] = a*this->pmegaData[j - 1] / 10 + result.pmegaData[j - 1] / 10;//把這一位在正常的計算結果基礎上加result[j - 1] / 10

			result.pmegaData[j - 1] = result.pmegaData[j - 1] % 10;//把前一位變成之前的前一位除10取餘
		}
		else {//中間的某一位

			result.pmegaData[j] = a*this->pmegaData[j - 1] / 10 + a*this->pmegaData[j] % 10 + result.pmegaData[j - 1] / 10;//把這一位在正常的計算結果基礎上加result[j - 1] / 10

			result.pmegaData[j - 1] = result.pmegaData[j - 1] % 10;//把前一位變成之前的前一位取餘數
		}
	}

	if (result.pmegaData[length] == 0) {//如果結果的最大位是0(說明多了一位)
		result.length -= 1;
	}

	return result;
}

//拓展並移動資料
megaData megaData::extend(int Len, int n, megaData & a)
{
	megaData result(Len);

	memset(result.pmegaData, 0, sizeof(int)*Len);

	memcpy(result.pmegaData + n, a.pmegaData, sizeof(int)*a.length);

	return result;
}

//打印出資料
void megaData::print()
{
	for (int i = length-1; i >=0; --i)cout << pmegaData[i];
	cout << endl;
}

//列印資料長度
void megaData::printLenth()
{
	cout << length << endl;
}


megaData::~megaData()
{
	delete[] pmegaData;
}

測試main函式:
//author			summer_awn
//date				2017/6/20


#include"megaData.h"

void main() {

	srand((unsigned)time(NULL));

	clock_t start, end;

	start = clock();

	megaData a(10000);
	cout << "a = ";
	//a.print();

	megaData b(3000);
	cout << "b = ";
	//b.print();

	megaData c = a + b;
	cout << "a + b = ";
	//c.print();

	megaData d = a * b;
	cout << "a * b =";
	//d.print();

	end = clock();

	float time = (float)(end - start) / 1000;

	cout << "time is:" << time << "s" << endl;

	system("pause");
}

執行結果:


說實話,我今天是第一次寫拷貝建構函式以及運算子的過載,,,,,,

很想知道我這一年都幹啥了,,,,,

em。。。本篇文章非教程(因為我啥也沒講,程式碼也挺亂的),就當是記錄我的學習過程了吧,

明天考大物,祈求不掛。。。