#include <iostream>
#include <vector>
using namespace std;
//desetichno -> dvoichno
vector<bool> DtoB(int val) {
vector<bool> binary;
bool negative = val < 0;
while (val != 0) {
binary.push_back(val % 2);
val /= 2;
}
binary.push_back(negative);
return binary;
}
//dvoichno -> desetichno
int BtoD() {
//lol nishto
return 0;
}
class Register {
int n; //razrqd
vector<bool> reg; //stoinost
bool V; //prepulvane
public:
//Constructors
Register(int nBits) {
this->n = nBits;
this->reg.assign(this->n, 0);
this->V = 0;
}
Register(int nBits, int val) {
this->n = nBits;
this->reg.assign(this->n, 0);
vector<bool> value = DtoB(val);
if (n <= value.size()) {
for (int i = 0; i < n; i++) {
reg[i] = value[i];
}
}
else {
for (int i = 0; i < value.size() - 1; i++) {
reg[i] = value[i];
}
reg[n - 1] = value[value.size() - 1];
}
this->V = 0;
}
//Setters, getters
bool getV() const{
return V;
}
void setV(bool v) {
this->V = v;
}
vector<bool> getReg() const {
return reg;
}
void setReg(vector<bool> binary) {
if (n <= binary.size()) {
for (int i = 0; i < n; i++) {
reg[i] = binary[i];
}
}
else {
for (int i = 0; i < binary.size(); i++) {
reg[i] = binary[i];
}
}
this->V = 0;
}
int getN() const {
return n;
}
//output
void print(char divider = ' ') const{
cout << reg[n - 1] << '|';
for (int i = n - 2; i >= 0; i--) {
cout << reg[i];
}
cout << divider;
}
void print(int start, int end, char divider = ' ') const {
cout << reg[end] << '|';
for (int i = end - 1; i >= start; i--) {
cout << reg[i];
}
cout << divider;
}
void printDouble(char divider = ' ') const {
int half = n / 2;
cout << reg[n - 1] << '|';
for (int i = n - 2; i >= half; i--) {
cout << reg[i];
}
cout << ' ';
for (int i = half - 1; i >= 0; i--) {
cout << reg[i];
}
cout << divider;
}
//operatori
std::vector<bool>::reference operator [] (unsigned int i){
return reg[i];
}
bool operator [] (unsigned int i) const{
return reg[i];
}
void operator << (int s) {
for (int i = n - 1; i >= s; i--) {
reg[i] = reg[i - s];
}
for (int i = 0; i < s; i++) {
reg[i] = 0;
}
}
void operator >> (int s) {
for (int i = 0; i < n - s; i++) {
reg[i] = reg[i + s];
}
for (int i = n - 1; i >= n - s; i--) {
reg[i] = 0;
}
}
Register operator + (const Register& b) const {
Register result(n);
bool carry = 0;
for (int i = 0; i < this->n; i++) {
result[i] = (reg[i] != b[i]) != carry;
carry = (reg[i] && b[i]) || ((reg[i] || b[i]) && carry);
}
//prepulvane
result.V = (reg[n - 1] && b[n - 1] && !result[n - 1])
|| (!reg[n - 1] && !b[n - 1] && result[n - 1]);
return result;
}
void operator ++ () {
int i;
for (i = 0; i < n; i++) {
if (reg[i] == 0) {
reg[i] = 1;
break;
}
else {
reg[i] = 0;
}
}
if (i == n - 1 && reg[i] == 1) {
this->V = 1; // prepulvane
}
}
//funkcii za preobrazuvane
void convertDK() {
for (int i = 0; i < n - 1; i++) {
reg[i] = !reg[i];
}
++*(this);
}
void negate() {
reg[n - 1] = !reg[n - 1];
for (int i = 0; i < n - 1; i++) {
reg[i] = !reg[i];
}
++ *(this);
}
};
void multiply(Register& x, Register& y) {
int n = y.getN();
int last = n * 2 - 1;
Register Mn(n * 2);
Register sum(n * 2);
Mn.setReg(x.getReg());
Mn << n;
sum.setReg(y.getReg());
//output
cout << "Mn: "; Mn.print(n, last, '\n');
cout << "Z: "; sum.printDouble(); cout << "Mt" << endl;
int i;
for (int i = 1; i < n; i++) {
if (sum[0] == 1) {
sum = sum + Mn;
//output
cout << " + |" << endl;
cout << "Mn: "; Mn.print(n, last, '\n');
cout << "------------------------" << endl;
cout << "Z: "; sum.printDouble('\n');
}
bool V = sum.getV();
bool c = sum[last];
bool sign = (c && !V) || (!c && V);
sum >> 1;
sum[last] = sign;
sum.setV(0);
//output
cout << "--> "; sum.printDouble();
cout << ' ' << i << ") S = (" << c << " * " << !V << ") + (" << !c << " * " << V << ") = " << sign;
cout << endl;
}
if (sum[0] == 1) {
Mn.negate();
sum = sum + Mn;
//output
cout << " + |" << endl;
cout << "-Mn: "; Mn.print(n, last, '\n');
cout << "------------------------" << endl;
cout << "Z: "; sum.printDouble('\n');
}
bool V = sum.getV();
bool c = sum[last];
bool sign = (c && !V) || (!c && V);
sum >> 1;
sum[last] = sign;
sum.setV(0);
//output
cout << "--> "; sum.printDouble();
cout << ' ' << n << ") S = (" << c << " * " << !V << ") + (" << !c << " * " << V << ") = " << sign;
cout << endl << endl;
cout << "Z = "; sum.printDouble('\n');
}
int main() {
Register regA(8, 56);
Register regB(8, -27);
regB.convertDK();
Register regC(8);
Register regD(8, -128);
regD.convertDK();
Register regE(8, -1);
regB.convertDK();
multiply(regA, regB);
//++regC;
//regC.print();
//++regC;
//regC.print();
//++regC;
//regC.print();
//regD.print();
//regD.convertDK();
//regD.print();
//++regD;
//regD.print();
//regE.print();
//regE.convertDK();
//regE.print();
//++regE;
//regE.print();
}