高精度加法和乘法的c++實現
阿新 • • 發佈:2019-02-03
上一篇用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。。。本篇文章非教程(因為我啥也沒講,程式碼也挺亂的),就當是記錄我的學習過程了吧,
明天考大物,祈求不掛。。。