30/09/2018, 16:09
Xử lý số lớn bằng C++ hướng đối tượng
Hôm nay rảnh ngồi làm chương trình tính số lớn:
#include<iostream>
#include<conio.h>
using namespace std;
class NumberXL {
private:
char numberXL[200]; //sâu ký tự
bool sign; //dấu, true=dương, false=âm
int len; //độ dài của số
public:
friend istream& operator>>(istream& in, NumberXL& numberXL);
friend ostream& operator<<(ostream& out, NumberXL& numberXL);
friend void BackWardsNumberXL(NumberXL& numberXL);
NumberXL operator+(NumberXL numberXL2);
};
void BackWardsNumberXL(NumberXL& numberXL) {
int len = numberXL.len;
for (int i = 0; i <= (len - 1) / 2; i++) {
char temp = numberXL.numberXL[i];
numberXL.numberXL[i] = numberXL.numberXL[len - 1 - i];
numberXL.numberXL[len - 1 - i] = temp;
}
}
istream& operator>>(istream& in, NumberXL& numberXL) {
char temp;
int i = 0;
//xét ký tự đầu tiêm, ,
do {
temp = _getch();
} while ((temp < '0' || temp > '9') && temp != '-' && temp != '+');
//nếu là '-'(số âm) thì numberXL.sign=false
if (temp == '-') {
numberXL.sign = false;
cout << temp;
}
//nếu là '+'(số dương) thì numberXL.sign=true
else if (temp == '+') {
numberXL.sign = true;
cout << temp;
}
//nếu ký tự đầu tiên không phải '+' hoặc '-' -> số dương numberXL.sign = true
//gán numberXL.sign = true
//gán ký tự đầu tiên bằng số vừa nhập
else {
numberXL.sign = true;
cout << temp;
numberXL.numberXL[i++] = temp;
}
//nhập số
do {
do {
temp = _getch();
} while ((temp < '0' || temp > '9') && temp != 13);
cout << temp;
if (temp == 13) {
temp = ' ';
}
numberXL.numberXL[i] = temp;
} while (numberXL.numberXL[i++] != ' ');
//độ dài của số
numberXL.len = strlen(numberXL.numberXL);
cout << endl;
return in;
}
ostream& operator<<(ostream& out, NumberXL& numberXL) {
int len = numberXL.len;
//nếu số âm thì in ra ký tư '-'
if (!numberXL.sign) {
out << "-";
}
//in số
for (int i = 0; i < len; i++) {
out << numberXL.numberXL[i];
}
return out;
}
NumberXL NumberXL::operator + (NumberXL numberXL2) {
NumberXL countXL;
int len_number1, len_number2, lenMIN, lenMAX;
char nho = '0';
//xét dấu của countXL.sign
//nếu cả 2 số cùng mang dâu dương thì tổng cũng mang dấu dương -> countXL.sign = true
if (this->sign == true && numberXL2.sign == true)
countXL.sign = true;
//nếu cả 2 số cùng mang dấu âm thì tổng cũng mang dấu âm -> countXL.sign = false
else if (this->sign == false && numberXL2.sign == false)
countXL.sign = false;
////số thứ nhất âm và số thứ hai dương -a+b=b-a
//else if (this->sign == true && numberXL2.sign == false)
// return numberXL2 - *this;
//lấy độ dài 2
//lưu trong len_number1, len_number2
len_number1 = this->len;
len_number2 = numberXL2.len;
//tìm độ dài
lenMIN = len_number1<len_number2 ? len_number1 : len_number2;
lenMAX = len_number1>len_number2 ? len_number1 : len_number2;
//đảo ngược hai xâu
BackWardsNumberXL(*this);
BackWardsNumberXL(numberXL2);
//tính tổng
//vị trí không lệch
for (int i = 0; i < lenMIN; i++) {
countXL.numberXL[i] = (this->numberXL[i] + numberXL2.numberXL[i] + nho - 3 * 48) % 10 + 48;
nho = (this->numberXL[i] + numberXL2.numberXL[i] + nho - 3 * 48) / 10 + 48;
}
//vị trí lệch
if (len_number1 > len_number2) {
for (int i = len_number2; i < len_number1; i++) {
countXL.numberXL[i] = (this->numberXL[i] + nho - 2 * 48) % 10 + 48;
nho = (this->numberXL[i] + nho - 2 * 48) / 10 + 48;
}
} else {
for (int i = len_number1; i < len_number2; i++) {
countXL.numberXL[i] = (numberXL2.numberXL[i] + nho - 2 * 48) % 10 + 48;
nho = (numberXL2.numberXL[i] + nho - 2 * 48) / 10 + 48;
}
}
//nếu sau tính tổng mà biến nho != '0' thì nho được lưu vào cuối xâu
if (nho != '0') {
countXL.numberXL[lenMAX] = nho;
//chèn ký tự kết thúc xâu
countXL.numberXL[lenMAX + 1] = ' ';
//độ đai của countXL
countXL.len = lenMAX + 1;
} else {
//chèn ký tự kết thúc xâu
countXL.numberXL[lenMAX] = ' ';
//độ đai của countXL
countXL.len = lenMAX;
}
//đảo ngược lại xâu rồi return
BackWardsNumberXL(*this);
BackWardsNumberXL(numberXL2);
BackWardsNumberXL(countXL);
return countXL;
}
void main() {
NumberXL a, b;
cout << "nhap so thu 1: ";
cin >> a;
cout << "nhap so thu 2: ";
cin >> b;
cout << a << "+" << b << "=" << a + b;
}
http://codepad.org/vQvbB6ZO
Chưa làm:
- chưa tính được -a+b=b-a, a+(-b) (ít thời gian quá nên chưa định nghĩa phép trừ)
- không backspace khi nhập số
Đã làm:
- tính được -a+(-b)=-(a+b)
PS:- code tào lao mong mọi người góp ý
P/S2: Post dùm LaCry TYar
Bài liên quan
File BigInt.h
File BigInt.cpp
Mình đã move bài này lên trên để cho dễ nhìn hơn
–Đạt
Rất hay, các bạn hãy tập làm quen với việc xử lý số lớn, đây không phải là một vấn đề quá khó, nhưng nó giúp ta hiểu được giới hạn của kiểu int là không thể tính toán trên số rất lớn. Và vì vậy chúng ta cần phải sử dụng các “thủ thuật” để thực hiện được trên giới hạn có sẵn.
I moved a post to a new topic: This-> trong C++ có ý nghĩa gì?
Vì code của @Gio là C nên Đạt đã di chuyển sang phần xử lý số lớn dùng C
I moved 3 posts to an existing topic: Xử lý số lớn - part1