Я сделал программу для BigInteger, в которой реализовал сложение и вычитание, но она дает неправильный результат. После нескольких дебютов я не могу понять проблему. Вот мой код: -
//
// Created by bothra on 09/07/20.
//
#include <sstream>
#include"BigInteger.h++"
BigInteger::BigInteger(std::string a) {
digits = a;
}
BigInteger BigInteger::operator+(BigInteger othr) {
return add(othr);
}
BigInteger BigInteger::operator-(BigInteger othr) {
return Subtract(othr);
}
bool BigInteger::operator>(BigInteger othr) {
if(digits.size() > othr.digits.size()){
return true;
}
else if(digits.size() < othr.digits.size()){
return false;
}
else{
for(int i = digits.size() - 1;i >= 0;i--){
if(digits[i] < othr.digits[i]){
return false;
}
}
return true;
}
}
bool BigInteger::operator==(BigInteger othr) {
if(digits.size() == othr.digits.size()){
int flag = 0;
for(int i = digits.size() - 1;i >= 0;i--){
if(digits[i] < othr.digits[i]){
return false;
}
if(digits[i] > othr.digits[i]){
flag = 1;
}
}
if(flag == 0){
return true;
}
}
return false;
}
BigInteger::BigInteger(int a) {
}
BigInteger BigInteger::add(BigInteger other) {
if(sign == other.sign) {
int base = 10;
BigInteger ans("0");
std::string a = digits;
std::string b = other.digits;
std::string result = "";
int s = 0;
int i = a.size() - 1;
int j = b.size() - 1;
while (i >= 0 || j >= 0 || s == 1) {
s += ((i >= 0) ? a[i] - '0' : 0);
s += ((j >= 0) ? b[j] - '0' : 0);
result = char(s % base + '0') + result;
s /= base;
i--;
j--;
}
ans.sign = sign;
ans.digits = result;
return ans;
}
else{
return Subtract(other);
}
}
BigInteger BigInteger::MakeShifting(BigInteger a,int stepnum){
std::string shifted = a.digits;
for (int i = 0 ; i < stepnum ; i++)
shifted = shifted + '0';
return shifted;
}
int makeEqualLength(std::string &str1, std::string &str2)
{
int len1 = str1.size();
int len2 = str2.size();
if (len1 < len2)
{
for (int i = 0 ; i < len2 - len1 ; i++)
str1 = '0' + str1;
return len2;
}
else if (len1 > len2)
{
for (int i = 0 ; i < len1 - len2 ; i++)
str2 = '0' + str2;
}
return len1; // If len1 >= len2
}
std::string getString(char x)
{
std::string s(1, x);
return s;
}
std::string DecimalToBinary(long long int number)
{
std::string result = "";
int base = 10;
if (number <= 0){
return "0";
}
else{
int i = 0;
char temp;
while (number > 0){
long long int num= number % base;
temp = num + '0';
result = getString(temp) + result;
number = number / base;
i++;
}
return result;
}
}
BigInteger BigInteger::Subtract(BigInteger a)
{
if(a.sign != sign){
a.sign = sign;
BigInteger ans = add(a);
ans.sign = sign;
return ans;
}
if(*this > a) {
BigInteger ans("0");
std::string rhs = a.digits;
std::string lhs = digits;
int length = makeEqualLength(lhs, rhs);
int diff;
std::string result;
int base = 10;
for (int i = length - 1; i >= 0; i--) {
diff = (lhs[i] - '0') - (rhs[i] - '0');
if (diff >= 0) {
result = DecimalToBinary(diff) + result;
} else {
for (int j = i - 1; j >= 0; j--) {
lhs[j] = ((lhs[j] - '0') - 1) % 10 + '0';
if (lhs[j] != '1') {
break;
}
}
result = DecimalToBinary(diff + base) + result;
}
}
ans.sign = sign;
ans.digits = result;
return ans;
}
if(*this == a){
return BigInteger("0");
}
else{
BigInteger ans("0");
std::string rhs = digits;
std::string lhs = a.digits;
int length = makeEqualLength(lhs, rhs);
int diff;
std::string result;
int base = 79;
for (int i = length - 1; i >= 0; i--) {
diff = (lhs[i] - '0') - (rhs[i] - '0');
if (diff >= 0) {
result = DecimalToBinary(diff) + result;
} else {
for (int j = i - 1; j >= 0; j--) {
lhs[j] = ((lhs[j] - '0') - 1) % 10 + '0';
if (lhs[j] != '1') {
break;
}
}
result = DecimalToBinary(diff + base) + result;
}
}
ans.sign = a.sign;
ans.digits = result;
return ans;
}
}
BigInteger BigInteger::Multiply(BigInteger other)
{
std::string X = digits;
std::string Y = other.digits;
int n = makeEqualLength(X, Y);
if (n == 1) return BigInteger(DecimalToBinary((X[0] - '0') * (Y[0] - '0')));
int fh = n/2; // First half of string, floor(n/2)
int sh = (n-fh); // Second half of string, ceil(n/2)
// Find the first half and second half of first string.
std::string Xl = X.substr(0, fh);
std::string Xr = X.substr(fh, sh);
// Find the first half and second half of second string
std::string Yl = Y.substr(0, fh);
std::string Yr = Y.substr(fh, sh);
// Recursively calculate the three products of inputs of size n/2
BigInteger P1 = BigInteger(Xl).Multiply(BigInteger(Yl));
BigInteger P2 = BigInteger(Xr).Multiply(BigInteger(Yr));
BigInteger P3 = (BigInteger(Xl)+BigInteger(Xr)).Multiply(BigInteger(Yl) + BigInteger(Yr));
// return added string version
return (P2 + MakeShifting(P1,2*(n - n/2))) + (MakeShifting(P3 - (P1 + P2) , n - n/2));
}
и заголовок:
//
// Created by bothra on 09/07/20.
//
#ifndef BIGINTEGER_BIGINTEGER_H
#define BIGINTEGER_BIGINTEGER_H
#include<iostream>
class BigInteger{
public:
std::string digits;
bool sign = false;//false indicates positive
BigInteger(int a);
BigInteger(std::string a);
BigInteger operator + (BigInteger othr);
BigInteger operator - (BigInteger othr);
bool operator > (BigInteger othr);
bool operator ==(BigInteger othr);
BigInteger add(BigInteger other);
BigInteger MakeShifting(BigInteger a,int stepnum);
BigInteger Subtract(BigInteger other);
BigInteger Multiply(BigInteger other);
};
#endif //BIGINTEGER_BIGINTEGER_H
Но умножение этого кода не работает. Он продолжает давать неправильный ответ.
Например, вот код драйвера: -
#include <iostream>
#include "BigInteger.h++"
int main() {
BigInteger a("429");
BigInteger b("429");
a = a.Multiply(b);
std::cout << a.digits;
return 0;
}
Здесь 429 * 429:
Output : 1397541
Output should have been : 184041
Пожалуйста, помогите меня. Заранее спасибо