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