lab3

Форк
0
/
BigRealNumber.cpp 
219 строк · 6.0 Кб
1
#include "BigRealNumber.h"
2

3
BigRealNumber::BigRealNumber() {
4
    intPrt = new short[1000];
5
    fractPrt = new short[1000];
6
    intPrtLen = 0;
7
    fractPrtLen = 0;
8
    isNegative = false;
9
}
10

11
BigRealNumber::BigRealNumber(const string &numb) {
12
    intPrt = new short[1000];
13
    fractPrt = new short[1000];
14

15
    isNegative = numb[0] == '-';
16
    intPrtLen = (int) numb.find('.');
17
    if (isNegative) {
18
        intPrtLen--;
19
    }
20
    fractPrtLen = (int) numb.length() - intPrtLen - 1;
21
    if (isNegative) {
22
        fractPrtLen--;
23
    }
24

25
    int j = isNegative ? 1 : 0;
26
    // копирование целой части
27
    for (int i = intPrtLen - 1; i >= 0; i--, j++) {
28
        intPrt[i] = (short) (numb.at(j) - '0');
29
    }
30
    j++;
31

32
    // копирование дробной части
33
    for (int i = fractPrtLen - 1; i >= 0; i--, j++) {
34
        fractPrt[i] = (short) (numb.at(j) - '0');
35
    }
36
}
37

38
BigRealNumber::~BigRealNumber() {
39
    delete fractPrt;
40
    delete intPrt;
41
}
42

43
string BigRealNumber::toString() const {
44
    string numb;
45
    if (isNegative) {
46
        numb.append(1, '-');
47
    }
48
    for (int i = intPrtLen - 1; i >= 0; i--) {
49
        numb.append(1, (char) ('0' + (int) intPrt[i]));
50
    }
51
    numb.append(1, '.');
52
    for (int i = fractPrtLen - 1; i >= 0; i--) {
53
        numb.append(1, (char) ('0' + (int) fractPrt[i]));
54
    }
55

56
    return numb;
57
}
58

59
BigRealNumber &BigRealNumber::operator=(const BigRealNumber &other) {
60
    isNegative = other.isNegative;
61
    fractPrtLen = other.fractPrtLen;
62
    intPrtLen = other.intPrtLen;
63

64
    fractPrt = new short[1000];
65
    intPrt = new short[1000];
66

67
    for (int i = 0; i < fractPrtLen; i++) {
68
        fractPrt[i] = other.fractPrt[i];
69
    }
70
    for (int i = 0; i < intPrtLen; i++) {
71
        fractPrt[i] = other.fractPrt[i];
72
    }
73

74
    return *this;
75
}
76

77
BigRealNumber BigRealNumber::operator+(const BigRealNumber &other) const {
78
    // this + other
79
    // -this + other
80
    // this + (-other)
81
    // -this + (-other)
82

83
    if (!(isNegative) && other.isNegative) { // this + (-other)
84
        return *this - other;
85
    } else if (isNegative && !other.isNegative) { // -this + other
86
        return other - *this;
87
    }
88

89
    BigRealNumber res;
90
    res.isNegative = isNegative;
91

92
    // сложение дробных частей
93
    short trans = addArraysToBRL(*this, other,
94
                                 res, true,
95
                                 false, 0);
96
    // сложение целых частей
97
    addArraysToBRL(*this, other,
98
                   res, false,
99
                   false, trans);
100

101
    return res;
102
}
103

104
BigRealNumber BigRealNumber::operator-(const BigRealNumber &other) const {
105
    // this - other
106
    // -this - other
107
    // -this - (-other)
108
    // this - (-other)
109

110
    if ((isNegative && other.isNegative) || (!(isNegative) && other.isNegative)) {
111
        return *this + other; // -this - other; this - (-other)
112
    } else if (isNegative && other.isNegative) {
113
        // -this - (-other)
114
        BigRealNumber res = other;
115
        res.isNegative = false;
116
        res = res - *this;
117
        return res;
118
    }
119

120
    BigRealNumber res;
121
}
122

123
// -------- вспомогательные методы --------------
124
void BigRealNumber::appendToInt(short number) {
125
    if (intPrtLen + 1 >= 1000) {
126
        throw runtime_error("Ошибка вычисления: целая часть "
127
                            "выходного числа содержит более 1000 цифр");
128
    }
129
    intPrt[intPrtLen++] = number;
130
}
131

132
bool BigRealNumber::appendToFract(short number) {
133
    if (fractPrtLen + 1 >= 1000) {
134
        return false;
135
    }
136
    fractPrt[fractPrtLen++] = number;
137
    return true;
138
}
139

140
short BigRealNumber::addArraysToBRL(
141
        const BigRealNumber &term1,
142
        const BigRealNumber &term2,
143
        BigRealNumber &res,
144
        bool addToFract,
145
        bool minusTerm2,
146
        short transfer
147
) const {
148
    int len1;
149
    int len2;
150
    if (addToFract) {
151
        len1 = term1.fractPrtLen;
152
        len2 = term2.fractPrtLen;
153
    } else {
154
        len1 = term1.intPrtLen;
155
        len2 = term2.intPrtLen;
156
    }
157

158
    short *bg; // больший массив
159
    short *sm; // меньший массив
160
    // если term2 наименьший массив
161
    bool minIsTerm2;
162
    // распределить массивы по длине
163
    if (len1 > len2) {
164
        bg = addToFract ? term1.fractPrt : intPrt;
165
        sm = addToFract ? term2.fractPrt : term2.intPrt;
166
        minIsTerm2 = true;
167
    } else {
168
        bg = addToFract ? term2.fractPrt : term2.intPrt;
169
        sm = addToFract ? term1.fractPrt : intPrt;
170
        minIsTerm2 = false;
171
    }
172

173
    // распределить длинны
174
    if (addToFract) {
175
        len1 = max(term1.fractPrtLen, term2.fractPrtLen);
176
        len2 = min(term1.fractPrtLen, term2.fractPrtLen);
177
    } else {
178
        len1 = max(term1.intPrtLen, term2.intPrtLen);
179
        len2 = min(term1.intPrtLen, term2.intPrtLen);
180
    }
181

182
    for (int i = 0, j = 0; i < len1; i++) {
183
        short n = transfer;
184
        // при сложении целых частей, начало меньшего массива прикладывается
185
        // к началу большего
186
        // при сложении дробных частей, конец меньшего массива прикладывается к
187
        // концу большего
188
        // пример 90.90; 1000.001
189
        // 0001.100
190
        // 09  . 09
191
        if ((i < len2 && !addToFract) || (i >= len1 - len2 && addToFract)) {
192
            n += sm[j++] * std::pow(-1, minIsTerm2 && minusTerm2);
193
        }
194
        n += bg[i] * std::pow(-1, !minIsTerm2 && minusTerm2);
195

196
        transfer = n > 9;
197
        if (n < 0 && (addToFract || i < len1 - 1)) {
198
            n += 10;
199
            transfer = -1;
200
        }
201
        n %= 10;
202
        if (addToFract) {
203
            if (!res.appendToFract(n)) {
204
                break;
205
            }
206
        } else {
207
            res.appendToInt(n);
208
        }
209
    }
210

211
    if (transfer > 0 && !addToFract) {
212
        res.appendToInt(transfer);
213
    }
214

215
    return transfer;
216
}
217

218
// 0.0 - 1.0
219
// 0-0
220

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.