#include <iostream>␍␊ |
#include "bigint.h"␍␊ |
␍␊ |
using namespace std;␍␊ |
␍␊ |
int bigint::sizeofchar(char* chr_arr)␍␊ |
{␍␊ |
␉char chr = '1';␍␊ |
␉int i = 0;␍␊ |
␉while(chr > 47 && chr < 58)␍␊ |
␉{␍␊ |
␉␉chr = chr_arr[i];␍␊ |
␉␉++i;␍␊ |
␉}␍␊ |
␉return i-1;␍␊ |
}␍␊ |
␍␊ |
bigint::bigint()␍␊ |
{␍␊ |
#if __DEBUG␍␊ |
␉cout << "Init big int" << endl;␍␊ |
#endif␍␊ |
}␍␊ |
void bigint::testHalfAddr(int xbit, int ybit)␍␊ |
{␍␊ |
␉this->xbit = xbit;␍␊ |
␉this->ybit = ybit;␍␊ |
␉halfaddr();␍␊ |
}␍␊ |
void bigint::testFullAddr(int xbit, int ybit, int cbit)␍␊ |
{␍␊ |
␉this->xbit = xbit;␍␊ |
␉this->ybit = ybit;␍␊ |
␉this->incbit = cbit;␍␊ |
␉fulladdr();␍␊ |
}␍␊ |
int bigint::getSbit()␍␊ |
{␍␊ |
␉return this->sbit;␍␊ |
}␍␊ |
int bigint::getCbit()␍␊ |
{␍␊ |
␉return this->cbit;␍␊ |
}␍␊ |
void bigint::halfaddr()␍␊ |
{␍␊ |
␉int cbit;␍␊ |
␉int sbit;␍␊ |
␉int xbit;␍␊ |
␉int ybit;␍␊ |
␉xbit = this->xbit;␍␊ |
␉ybit = this->ybit;␍␊ |
␉int notcbit;␍␊ |
␉__asm{␍␊ |
␉␉␉mov␉eax, xbit␍␊ |
␉␉␉and␉eax, ybit␍␊ |
␉␉␉mov cbit, eax␉␉␉␉;cbit = xbit AND ybit␍␊ |
␉␉␉␍␊ |
␉␉␉mov␉ebx, cbit␍␊ |
␉␉␉mov␉notcbit, ebx␍␊ |
␉␉␉not␉notcbit␉␉␉␉␉;notcbit = NOT cbit␍␊ |
␉␉␉mov␉eax, xbit␍␊ |
␉␉␉or␉eax, ybit␍␊ |
␉␉␉and␉eax, notcbit␍␊ |
␉␉␉mov␉sbit, eax␉␉␉␉;sbit = (xbit OR ybit) AND notcbit␍␊ |
␉}␍␊ |
␉this->cbit = cbit;␍␊ |
␉this->sbit = sbit;␍␊ |
}␍␊ |
void bigint::fulladdr()␍␊ |
{␍␊ |
␉int cbit;␍␊ |
␉int cbit1;␍␊ |
␉int sbit;␍␊ |
␉int xbit = this->xbit;␍␊ |
␉int ybit = this->ybit;␍␊ |
␉int incbit = this->incbit;␍␊ |
␉halfaddr();␍␊ |
␉cbit = this->cbit;␍␊ |
␉sbit = this->sbit;␍␊ |
␉␉__asm {␍␊ |
␉␉␉mov␉ebx, cbit␍␊ |
␉␉␉mov cbit1, ebx␉␉␉␉;cbit1 = cbit␍␊ |
␉␉␉␍␊ |
␉␉␉mov ebx, sbit␍␊ |
␉␉␉mov xbit, ebx␉␉␉␉;xbit = sbit␍␊ |
␉␉␉␍␊ |
␉␉␉mov ebx, incbit␍␊ |
␉␉␉mov ybit, ebx␉␉␉␉;ybit = incbit␍␊ |
␉␉}␍␊ |
␉␉this->xbit = xbit;␍␊ |
␉␉this->ybit = ybit;␍␊ |
␉␉halfaddr();␍␊ |
␉␉cbit = this->cbit;␍␊ |
␉␉__asm {␍␊ |
␉␉␉;call halfaddr␉␉␉␉;halfaddr(xbit, ybit)␍␊ |
␉␉␉␍␊ |
␉␉␉mov ebx, cbit␍␊ |
␉␉␉or ebx, cbit1␍␊ |
␉␉␉␍␊ |
␉␉␉mov cbit, ebx␉␉␉␉;cbit = cbit OR cbit1␍␊ |
␉}␍␊ |
␉␉this->cbit = cbit;␍␊ |
}␍␊ |
int bigint::length()␍␊ |
{␍␊ |
␉int sze = 0;␍␊ |
␉int lng = this->num.size();␍␊ |
␉int * arr = this->getNumber();␍␊ |
␉__asm {␍␊ |
␉␉mov ecx, lng␍␊ |
␉␉mov eax, lng␍␊ |
␉␉mov edx, 4␍␊ |
␉␉mul edx␍␊ |
␉␉sub eax, 4␍␊ |
␉␉mov ebx, eax␍␊ |
␉␉mov eax, arr␍␊ |
␉␉mov edx, 0␍␊ |
lpcnt:␍␊ |
␉␉cmp edx, [eax+ebx]␍␊ |
␉␉jne lpcnt2␍␊ |
␉␉dec ebx␍␊ |
␉␉dec ebx␍␊ |
␉␉dec ebx␍␊ |
␉␉dec ebx ;is dec 4 faster than sub 4?␍␊ |
␉␉␉␉;who knows?␍␊ |
␉␉loop lpcnt␍␊ |
lpcnt2:␍␊ |
␉␉mov ecx, 4␍␊ |
␉␉mov eax, ebx␍␊ |
␉␉div ecx␍␊ |
␉␉inc eax␍␊ |
␉␉mov sze, eax␍␊ |
␉}␍␊ |
␉/*for(int i = this->num.size() -1; i > 0; i--)␍␊ |
␉{␍␊ |
␉␉if (num[i] != 0)␍␊ |
␉␉{␍␊ |
␉␉␉size = i;␍␊ |
␉␉␉break;␍␊ |
␉␉}␍␊ |
␉}*/␍␊ |
␉delete arr;␍␊ |
␉return sze;␍␊ |
}␍␊ |
int* bigint::getNumber()␍␊ |
{␍␊ |
␉int* tmp; //I hope the caller remembers to delete this! ):␍␊ |
␉tmp = new int[this->num.size()+2];␍␊ |
␉for(int i = 0; i < (int)this->num.size(); i++)␍␊ |
␉␉tmp[i] = this->num[i];␍␊ |
␉return tmp;␍␊ |
}␍␊ |
int bigint::isnum(int n)␍␊ |
{␍␊ |
␉if (n > 0)␍␊ |
␉␉return n;␍␊ |
␉else␍␊ |
␉␉return 0;␍␊ |
}␍␊ |
bigint bigint::operator+(bigint& num)␍␊ |
{␍␊ |
␉bigint ret;␍␊ |
␉int* src_n = this->getNumber();␍␊ |
␉int* src2_n = num.getNumber();␍␊ |
␉int nsize = 0;␍␊ |
␉//int lng = (this->length() > num.length()) ? (num.length()) : (this->length());␍␊ |
␉//int lngarr = (this->length() < num.length()) ? (num.length()) : (this->length());␍␊ |
␉//int * dest = new int[lngarr+1];␍␊ |
␉int carry = 0;␍␊ |
␉if (this->length() > num.length())␍␊ |
␉{␍␊ |
␉␉for (int i = 0; i < num.length() + 1; ++i)␍␊ |
␉␉{␍␊ |
␉␉␉src_n[i] = src_n[i] + this->isnum(src2_n[i]) + carry;␍␊ |
␉␉␉carry = 0;␍␊ |
␉␉␉if (src_n[i] >= 10)␍␊ |
␉␉␉{␍␊ |
␉␉␉␉src_n[i] -= 10;␍␊ |
␉␉␉␉carry = 1;␍␊ |
␉␉␉}␍␊ |
␉␉}␍␊ |
␉␉int n = this->length();␍␊ |
␉␉if (this->length() < num.length())␍␊ |
␉␉␉src2_n[n] += carry;␍␊ |
␉␉else␍␊ |
␉␉␉src2_n[n] = carry;␍␊ |
␉␉//src_n[n] += carry;␍␊ |
␉␉char * tmp;␍␊ |
␉␉tmp = new char[this->num.size()+1];␍␊ |
␉␉int x = 0;␍␊ |
␉␉if (carry)␍␊ |
␉␉␉nsize = this->num.size();␍␊ |
␉␉else␍␊ |
␉␉␉nsize = this->num.size() - 1;␍␊ |
␉␉for (int i = nsize; i >= 0; --i) //reverse, reverse!␍␊ |
␉␉{␍␊ |
␉␉␉tmp[x] = src_n[i] + 48;␍␊ |
␉␉␉++x;␍␊ |
␉␉}␍␊ |
␍␊ |
␉␉ret.equals(tmp);␍␊ |
␉␉delete tmp;␍␊ |
␉␉//this->num.clear();␍␊ |
␍␊ |
␉} else {␍␊ |
␉␉for (int i = 0; i < this->length() + 1; ++i)␍␊ |
␉␉{␍␊ |
␉␉␉src2_n[i] = this->isnum(src_n[i]) + src2_n[i] + carry;␍␊ |
␉␉␉carry = 0;␍␊ |
␉␉␉if (src2_n[i] >= 10)␍␊ |
␉␉␉{␍␊ |
␉␉␉␉src2_n[i] -= 10;␍␊ |
␉␉␉␉carry = 1;␍␊ |
␉␉␉}␍␊ |
␉␉}␍␊ |
␉␉int n = num.length();␍␊ |
␉␉if (this->length() > num.length())␍␊ |
␉␉␉src2_n[n] += carry;␍␊ |
␉␉else␍␊ |
␉␉␉src2_n[n] = carry;␍␊ |
␉␉char * tmp;␍␊ |
␉␉tmp = new char[num.num.size()+1];␍␊ |
␉␉int x = 0;␍␊ |
␉␉if (carry)␍␊ |
␉␉␉nsize = num.num.size();␍␊ |
␉␉else␍␊ |
␉␉␉nsize = num.num.size() - 1;␍␊ |
␍␊ |
␉␉for (int i = nsize; i >= 0; --i) //reverse, reverse!␍␊ |
␉␉{␍␊ |
␉␉␉tmp[x] = src2_n[i] + 48;␍␊ |
␉␉␉++x;␍␊ |
␉␉}␍␊ |
␉␉ret.equals(tmp);␍␊ |
␉␉delete tmp;␍␊ |
␉␉//num.num.clear();␍␊ |
␉}␍␊ |
␉//dest[lng] += carry;␍␊ |
␉//for (int i = 0; i < (int)num.num.size(); i++)␍␊ |
␉//␉cout << src2_n[i];␍␊ |
␉//delete dest;␍␊ |
␉delete [] src_n;␍␊ |
␉delete [] src2_n;␍␊ |
␉return ret;␍␊ |
}␍␊ |
void bigint::equals(char* cn)␍␊ |
{␍␊ |
␉this->num.clear();␍␊ |
␉//cout << this->sizeofchar(chr_arr) << endl;␍␊ |
␉//int nDigits = this->sizeofchar(chr_arr);␍␊ |
␉int i;␍␊ |
␉//pushback(num);␍␊ |
␉//we have to do this in reverse␍␊ |
␉__asm {␍␊ |
␉␉;push num␍␊ |
␉␉push cn␍␊ |
␉␉mov ecx, this␍␊ |
␉␉call bigint::sizeofchar␍␊ |
␉␉mov ecx, eax␍␊ |
␉␉mov i, ecx␍␊ |
␉␉dec i␍␊ |
lpprep:␍␊ |
␉␉/*␍␊ |
␉␉␉We need to use assembly here to convert a ASCII number to an actual number␍␊ |
␉␉*/␍␊ |
␉␉;char_tmp[0] = chr_arr[i];␍␊ |
␉␉;lea ax, char_tmp[0]␍␊ |
␉␉mov eax, cn␍␊ |
␉␉sub edx, edx␍␊ |
␉␉mov ebx, i␍␊ |
␉␉mov dl, [eax+ebx]␍␊ |
␉␉sub dl, 48␍␊ |
␉␉;mov num, edx␍␊ |
␉␉␉//ints are 4?␍␊ |
␉␉;mov eax, edx␍␊ |
␉␉//need to push ecx BEFORE you push the number, right?␍␊ |
␉␉push ecx␍␊ |
␉␉push edx␍␊ |
␉␉mov ecx, this␍␊ |
␉␉call␉bigint::pushback␍␊ |
␉␉pop ecx␍␊ |
␉␉dec i␍␊ |
␉␉;push ecx␍␊ |
␉␉//num = atoi(char_tmp[0]);␍␊ |
␉␉//pushback(num);␍␊ |
␉␉;pop ecx␍␊ |
␉␉;push ecx␍␊ |
␉␉loop lpprep␍␊ |
␉␉;pop ecx␍␊ |
␉}␍␊ |
␉/*for(int i = nDigits-1; i >= 0; --i)␍␊ |
␉{␍␊ |
␉␉char_tmp[0] = chr_arr[i];␍␊ |
␉␉num = atoi(char_tmp);␍␊ |
␉␉this->num.push_back(num);␍␊ |
␉}*/␍␊ |
␉//return *this;␍␊ |
}␍␊ |
ostream& operator<<(ostream& os,bigint& bi)␍␊ |
{␍␊ |
␉int size = bi.num.size();␍␊ |
␉int* asm_bi;␍␊ |
␉asm_bi = new int[size];␍␊ |
␉for (int x = 0; x < size; ++x)␍␊ |
␉␉asm_bi[x] = bi.num[x];␍␊ |
␉int arry[] = {2,0};␍␊ |
␉int n1;␍␊ |
␉int nDigits = bi.length();␍␊ |
␉//int i;␍␊ |
␉__asm {␍␊ |
␉␉mov ecx, nDigits␍␊ |
␉␉mov eax, nDigits␍␊ |
␉␉mov edx, 4␍␊ |
␉␉mul edx␍␊ |
␉␉mov ebx, eax␍␊ |
␉␉sub ebx, 4␍␊ |
␉␉push ebx␍␊ |
lpout:␍␊ |
␉␉mov eax, asm_bi␍␊ |
␉␉pop ebx␍␊ |
␉␉mov edx, [eax+ebx]␍␊ |
␉␉sub ebx, 4␍␊ |
␉␉mov n1, edx␍␊ |
␉␉push ebx␍␊ |
␉␉push ecx␍␊ |
␉}␍␊ |
␉os << n1;␍␊ |
␉__asm {␍␊ |
␉␉pop ecx␍␊ |
␉␉loop lpout␍␊ |
␉␉pop ebx␍␊ |
␉}␍␊ |
␉delete[] asm_bi;␍␊ |
␉asm_bi = NULL;␍␊ |
␉return os;␍␊ |
}␍␊ |
void bigint::pushback(int n)␍␊ |
{␍␊ |
␉this->num.push_back(n);␍␊ |
}␍␊ |
␍␊ |
bigint::bigint(char* chr_arr)␍␊ |
{␍␊ |
␉this->equals(chr_arr);␍␊ |
} |