Skip to content

Instantly share code, notes, and snippets.

@andermirik
Created March 20, 2018 18:39
Show Gist options
  • Save andermirik/48f615ff3d695a4891baceef345c234b to your computer and use it in GitHub Desktop.
Save andermirik/48f615ff3d695a4891baceef345c234b to your computer and use it in GitHub Desktop.
класс для сложения двоичных чисел используя длинную арифметику.
//файл 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