-
-
Save andermirik/48f615ff3d695a4891baceef345c234b to your computer and use it in GitHub Desktop.
класс для сложения двоичных чисел используя длинную арифметику.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//файл bint.h | |
#pragma once | |
#include "iostream" | |
using namespace std; | |
class bint { | |
friend bint *sum_pos(bint &, bint&, int); | |
friend bint *dif(bint &, bint &); | |
public: | |
bint(); | |
~bint(); | |
bint(int); | |
bint& operator+(bint &); | |
void operator +=(bint&); | |
bint& operator++(); | |
bint& operator++(int); | |
bint(const bint &); | |
friend istream & operator>>(istream &, bint &); | |
friend ostream & operator<<(ostream &, bint &); | |
operator double(); | |
private: | |
int *bin; | |
int size; | |
bool positive; | |
}; | |
//файл bint.cpp | |
#include "bint.h" | |
#include "conio.h" | |
bint::bint() { | |
//cout << "êîíñòðóêòîð" << endl; | |
size = 1; | |
bin = new int[size]; | |
bin[0] = 0; | |
positive = true; | |
} | |
bint::~bint() { | |
//cout << "äåñòðóêòîð"<<endl; | |
if (bin && size == 1) | |
delete bin; | |
else if (bin) | |
delete[] bin; | |
} | |
bint::bint(int x) { | |
size = 0; | |
positive = true; | |
if (x == 0) { | |
bin = new int[++size]; | |
bin[0] = 0; | |
return; | |
}else if (x < 0) { | |
positive = false; | |
x = abs(x); | |
} | |
int arr[8 * sizeof(int)];//íå çàáûòü ïðî íàïðàâëåíèå | |
while (x) { | |
arr[size] = x & 1; | |
x >>= 1; | |
size++; | |
} | |
bin = new int[size]; | |
memcpy(bin, arr, sizeof(int)*size); | |
} | |
bint::bint(const bint & orig) { | |
// cout << "êîïèðóþùèé êîíñòðóêòîð"<<endl; | |
size = orig.size; | |
positive = orig.positive; | |
bin = new int[orig.size]; | |
memcpy(bin, orig.bin, size * sizeof(int)); | |
} | |
inline bint* sum_pos(bint & A, bint & B, int mode=0) | |
{ | |
bint* result = new bint(); | |
int result_size = 0; | |
if(!mode) | |
A.size > B.size ? result_size = A.size + 1 : result_size = B.size + 1; | |
else result_size = A.size; | |
result->size = result_size; | |
result->bin = new int[result_size]; | |
int shift = 0; | |
int temp_int = 0; | |
for (int i = 0; i < result_size; i++) { | |
temp_int = 0; | |
if (A.size>i) | |
temp_int += A.bin[i]; | |
if (B.size>i) | |
temp_int += B.bin[i]; | |
temp_int += shift; | |
shift = temp_int >> 1; | |
result->bin[i] = temp_int & 1; | |
} | |
if (mode&&(*result).bin[result->size - 1] == 1) | |
result->bin[result->size - 1] = 0; | |
while (result->bin[result->size-1] == 0 && result->size>1) { | |
int *Resize = new int[result->size - 1]; | |
for (int i = result->size-2; i >=0; i--) { | |
Resize[i] = result->bin[i]; | |
} | |
result->bin = new int[result->size - 1]; | |
result->size--; | |
for (int i = 0; i < result_size - 1; i++) { | |
result->bin[i] = Resize[i]; | |
} | |
result_size--; | |
} | |
return result; | |
} | |
inline bint* dif(bint &A, bint &B) { | |
bint* result = new bint(); | |
bint one(1); | |
if (A.size > B.size) { | |
bint copy_of_B = B; | |
int *Resize = new int[A.size]; | |
for (int i = 0; i < A.size; i++) | |
Resize[i] = 0; | |
for (int i = A.size - B.size; i < A.size; i++) { | |
Resize[i - (A.size - B.size)] = copy_of_B.bin[i - (A.size - B.size)]; | |
} | |
copy_of_B.size = A.size; | |
cout << (bool)A.size<< (bool)B.size<<"\b\b \b\b"; | |
copy_of_B.positive = true; | |
memcpy(copy_of_B.bin, Resize, sizeof(int) * copy_of_B.size); | |
for (int i = 0; i < A.size; i++) | |
copy_of_B.bin[i] = !copy_of_B.bin[i]; | |
bint copy; | |
copy = *sum_pos(A,copy_of_B, 0); | |
result = sum_pos(copy, one, 1); | |
} | |
else if(B.size>A.size){ | |
bint copy_of_A = A; | |
int *Resize = new int[B.size]; | |
for (int i = 0; i < B.size; i++) | |
Resize[i] = 0; | |
for (int i = B.size - A.size; i < B.size; i++) { | |
Resize[i - (B.size - A.size)] = copy_of_A.bin[i - (B.size - A.size)]; | |
} | |
copy_of_A.size = B.size; | |
cout << (bool)A.size << (bool)B.size << "\b\b \b\b"; | |
copy_of_A.positive = true; | |
memcpy(copy_of_A.bin, Resize, sizeof(int) * copy_of_A.size); | |
for (int i = 0; i < B.size; i++) | |
copy_of_A.bin[i] = !copy_of_A.bin[i]; | |
bint copy; | |
copy = *sum_pos(copy_of_A, B, 0); | |
result = sum_pos(copy, one, 1); | |
result->positive = false; | |
} | |
else if (A.size == B.size) { | |
int AbiggestB = 0;//A>B k = 1 A<B k = 0 | |
for (int i = A.size - 1; i >= 0; i--) { | |
if (A.bin[i] > B.bin[i]) { | |
AbiggestB = 1; | |
break; | |
} | |
if (A.bin[i] < B.bin[i]) { | |
AbiggestB = 0; | |
break; | |
} | |
} | |
if (AbiggestB) { | |
bint copy_of_B = B; | |
cout << (bool)A.size << (bool)B.size << "\b\b \b\b"; | |
copy_of_B.positive = true; | |
cout << "A " << A << endl; | |
cout << "B " << B << endl; | |
for (int i = 0; i < B.size; i++) | |
copy_of_B.bin[i] = !copy_of_B.bin[i]; | |
cout << "copy B " << copy_of_B << endl; | |
bint copy; | |
copy = *sum_pos(A, copy_of_B, 0); | |
cout << copy << endl; | |
result = sum_pos(copy, one, 1); | |
cout << *result << endl; | |
result->positive = true; | |
} | |
else{ | |
bint copy_of_A = A; | |
cout << (bool)A.size << (bool)B.size << "\b\b \b\b"; | |
copy_of_A.positive = true; | |
for (int i = 0; i < B.size; i++) | |
copy_of_A.bin[i] = !copy_of_A.bin[i]; | |
bint copy; | |
copy = *sum_pos(copy_of_A, B, 0); | |
result = sum_pos(copy, one, 1); | |
result->positive = false; | |
} | |
} | |
return result; | |
} | |
bint& bint::operator+(bint &second) { | |
bint* result = NULL; | |
if (this->positive == false && second.positive == false) {// A- B- => -(A+B) | |
result = sum_pos(*this, second); | |
(*result).positive = false; | |
} | |
else if (this->positive == false) {//A- B+ => B-A | |
result = dif(second, *this); | |
} | |
else if (second.positive == false) {//A+ B- =>A-B | |
result = dif(*this, second); | |
} | |
else { | |
result = sum_pos(*this, second); | |
} | |
if (result->size == 1 && result->bin[0] == 0) | |
result->positive = true; | |
return *result; | |
} | |
void bint::operator+=(bint & second) { | |
bint* result = NULL; | |
if (this->positive == false && second.positive == false) {// A- B- => -(A+B) | |
result = sum_pos(*this, second, 0); | |
(*result).positive = false; | |
} | |
else if (this->positive == false) {//A- B+ => B-A | |
result = dif(second, *this); | |
} | |
else if (second.positive == false) {//A+ B- =>A-B | |
result = dif(*this, second); | |
} | |
else { | |
result = sum_pos(*this, second, 0); | |
} | |
if (result->size == 1 && result->bin[0] == 0) | |
result->positive = true; | |
*this = *result; | |
} | |
/* | |
bint & bint::operator++() { | |
bint one = 1; | |
bint* result = NULL; | |
if (this->positive == false) {//A- B+ => B-A | |
result = dif(one, *this); | |
} | |
else { | |
result = sum_pos(*this, one); | |
} | |
if (result->size == 1 && result->bin[0] == 0) | |
result->positive = true; | |
*this = *result; | |
return *this; | |
} | |
bint bint::operator++(int x) { | |
bint copy = *this; | |
bint one = 1; | |
bint* result = NULL; | |
if (this->positive == false) {//A- B+ => B-A | |
result = dif(one, *this); | |
} | |
else { | |
result = sum_pos(*this, one); | |
} | |
if (result->size == 1 && result->bin[0] == 0) | |
result->positive = true; | |
*this = *result; | |
return copy; | |
} | |
*/ | |
bint& bint::operator++() { | |
bool zero = false; | |
if (positive) | |
{ | |
for (int i = 0; i <size; i++) | |
{ | |
if (bin[i] == 0) { | |
zero = true; | |
break; | |
} | |
} | |
if (!zero) | |
{ | |
bin = new int[++size]; | |
for (int i = size-1; i >=0; i--) | |
bin[i] = 0; | |
bin[size-1] = 1; | |
} | |
else | |
{ | |
int i = 0; | |
while (bin[i] == 1) { | |
bin[i++] = 0; | |
} | |
bin[i]++; | |
} | |
} | |
else | |
{ | |
int i = 0; | |
while (bin[i] == 0) { | |
bin[i++] = 1; | |
} | |
bin[i]--; | |
int start_size = size; | |
if (bin[size - 1] == 0 && size>1) { | |
int *Resize = new int[size - 1]; | |
for (int i = size - 2; i >= 0; i--) { | |
Resize[i] = bin[i]; | |
} | |
bin = new int[size - 1]; | |
size--; | |
for (int i = 0; i < start_size - 1; i++) { | |
bin[i] = Resize[i]; | |
} | |
start_size--; | |
delete[] Resize; | |
} | |
if (size == 1 && bin[0] == 0) | |
positive = true; | |
} | |
return *this; | |
} | |
bint& bint::operator++(int x) { | |
bint copy = *this; | |
bool zero = false; | |
if (positive) | |
{ | |
for (int i = 0; i <size; i++) | |
{ | |
if (bin[i] == 0) | |
{ | |
zero = true; | |
break; | |
} | |
} | |
if (!zero) | |
{ | |
bin = new int[++size]; | |
for (int i = size - 1; i >= 0; i--) | |
bin[i] = 0; | |
bin[size - 1] = 1; | |
} | |
else | |
{ | |
int i = 0; | |
while (bin[i] == 1) | |
{ | |
bin[i++] = 0; | |
} | |
bin[i]++; | |
} | |
} | |
else | |
{ | |
int i = 0; | |
while (bin[i] == 0) | |
{ | |
bin[i++] = 1; | |
} | |
bin[i]--; | |
int start_size = size; | |
if (bin[size - 1] == 0 && size>1) | |
{ | |
int *Resize = new int[size - 1]; | |
for (int i = size - 2; i >= 0; i--) | |
{ | |
Resize[i] = bin[i]; | |
} | |
bin = new int[size - 1]; | |
size--; | |
for (int i = 0; i < start_size - 1; i++) | |
{ | |
bin[i] = Resize[i]; | |
} | |
start_size--; | |
delete[] Resize; | |
} | |
if (size == 1 && bin[0] == 0) | |
positive = true; | |
} | |
return copy; | |
} | |
ostream & operator<<(ostream & output, bint &b1) | |
{ | |
if (!b1.positive) | |
output<<'-'; | |
for (int i = b1.size-1; i >= 0; i--) { | |
output<<b1.bin[i]; | |
} | |
return output; | |
} | |
istream & operator>>(istream & input, bint & b1) | |
{ | |
const int size_buffer = 1024; | |
char buf[size_buffer]; | |
int buf_size = 0; | |
bool one = false; | |
bool only_zero = false; | |
char key; | |
do { | |
key = _getch(); | |
if (buf_size == 0) { | |
b1.positive = true; | |
only_zero = false; | |
one = false; | |
} | |
if (key == 8 && buf_size > 0) { | |
_putch('\b'); | |
_putch(' '); | |
_putch('\b'); | |
buf_size--; | |
continue; | |
} | |
if (buf_size == 0 && key == '-') { | |
_putch('-'); | |
b1.positive = false; | |
buf[size_buffer-1-buf_size++] = '-'; | |
continue; | |
} | |
if (buf_size == 0 && key == '+') { | |
_putch('+'); | |
b1.positive = true; | |
buf[size_buffer-1-buf_size++] = '+'; | |
continue; | |
} | |
if ((key == '0' && only_zero == false && buf_size == 0) || ((buf[0] == '+' || buf[0] == '-') && buf_size == 1 && key == '0')) { | |
_putch(key); | |
buf[size_buffer-1-buf_size++] = key; | |
only_zero = true; | |
b1.positive = true; | |
continue; | |
} | |
if (key == '0' && buf_size < size_buffer && one) { | |
_putch(key); | |
buf[size_buffer-1-buf_size++] = key; | |
continue; | |
} | |
if (key == '1'&&only_zero == true && buf_size < size_buffer) { | |
_putch('\b'); | |
_putch(key); | |
buf[size_buffer-1-buf_size - 1] = key; | |
one = true; | |
only_zero = false; | |
continue; | |
} | |
if (key == '1' && buf_size < size_buffer) { | |
_putch(key); | |
buf[size_buffer-1-buf_size] = key; | |
buf_size++; | |
one = true; | |
continue; | |
} | |
} while (key != 13); | |
if (buf[size_buffer-1] == '+' || buf[size_buffer-1] == '-') { | |
b1.size = buf_size - 1; | |
b1.bin = new int[b1.size]; | |
for (int i = size_buffer-2; i >size_buffer -2- buf_size; i--) { | |
b1.bin[size_buffer-i - 2] = (int)buf[i] - 48; | |
} | |
} | |
else { | |
b1.size = buf_size; | |
b1.bin = new int[b1.size]; | |
for (int i = size_buffer-1; i >size_buffer-1- buf_size; i--) { | |
b1.bin[b1.size-(size_buffer-i-1)-1] = (int)buf[i] - 48; | |
} | |
} | |
_putch('\n'); | |
return input; | |
} | |
bint::operator double() { | |
if (size < sizeof(int) * 8) { | |
int result = 0; | |
for (int i = 0; i < size; i++) { | |
result += bin[i] << i; | |
} | |
return (double)result; | |
} | |
else { | |
cerr << "äâîè÷íîå ÷èñëî íå âëåçëî â ðàçðÿäíóþ ñåòêó __int32" << endl; | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment