#それは何か。
それはですね。2進数の加算や合成です。
#何があるか。
And,Not,OR,Xor,Nor,Nand,Equalの演算があります。
説明は難しいのでコード見てください。
#Code.
Code
#include <iostream>
#include <tuple>
#include <limits>
//https://ja.wikipedia.org/wiki/加算器
bool And(const bool& A, const bool& B) {
return A & B;
}
bool OR(const bool& A, const bool& B) {
return A | B;
}
bool Not(const bool& A) {
return !A;
// return ~A;//why not work this line...
}
bool Xor(const bool& A, const bool& B) {
return A ^ B;
}
bool Nand(const bool& A, const bool& B) {
return !(A & B);
}
bool Nor(const bool& A, const bool& B) {
return !(A | B);
}
bool Equal(const bool& A, const bool& B) {
return !(A ^ B);
}
std::tuple<bool, bool> HarfAdder(const bool& A, const bool& B) {//std::get<0>() => S. std::get<1>() => C.
bool S = Xor(A, B);
bool C = And(A, B);
return { S,C };
}
std::tuple<bool, bool> FullAdder(const bool& A, const bool& B,const bool& X) {//std::get<0>() => S. std::get<1>() => C.
auto AA = HarfAdder(A, B);
auto BB = HarfAdder(std::get<0>(AA), X);
bool S = std::get<0>(BB);
bool C = OR(std::get<1>(AA), std::get<1>(BB));
return { S,C };
}
template<class T>
T Add(const T& A, const T& B) {
std::size_t L = std::numeric_limits<T>::digits;
std::tuple<bool, bool> X{ false,false };
T V(0);
L += L % 2;
for (std::size_t i = 0; i < L; i++) {
X = FullAdder(((A & (1 << i)) ? true : false), ((B & (1 << i)) ? true : false), std::get<1>(X));
V |= (std::get<0>(X) ? 1 : 0) << i;
}
return V;
}
template<class T>
T Sub(const T& A, const T& B) {
std::size_t L = std::numeric_limits<T>::digits;
L += L % 2;
T V(0);
std::tuple<bool, bool> X{ false,true };
for (std::size_t i = 0; i < L; i++) {
X = FullAdder(((A & (1 << i)) ? true : false), Not((B & (1 << i)) ? true : false), std::get<1>(X));
V |= (std::get<0>(X) ? 1 : 0) << i;
}
return V;
}
int main() {
int A = 10;
int B = -10;
int X1 = Add(A, A); std::cout << "Add:" << A << '+' << A <<"=="<<X1<< std::endl;
int X2 = Add(A, B); std::cout << "Add:" << A << '+' << B <<"=="<<X2<<std::endl;
int X3 = Add(A, B*2); std::cout << "Add:" << A << '+' << B*2 <<"=="<<X3<< std::endl;
int Y1 = Sub(A, A); std::cout << "Sub:" << A << '-' << A <<"=="<<Y1<< std::endl;
int Y2 = Sub(A, B); std::cout << "Sub:" << A << '-' << B <<"=="<<Y2<<std::endl;
int Y3 = Sub(A, B * 2); std::cout << "Sub:" << A << '-' << B * 2 << "==" << Y3 << std::endl;
int Y4 = Sub(A/2, A); std::cout << "Sub:" << A/2 << '-' << A << "==" << Y4 << std::endl;
return 0;
}
#終わりに
超手抜きです。乗算器と除算器が難しすぎて泣けるので書いてないです。
それでは・・・。
#追記
掛け算を発見したので追記しておきます。筆算法です。
なお、デバッグはほとんどやってありません。
code.cpp
#include <limits>
template<class T>
T Mul(const T& A,const T& B) {
T C(0);
for (std::size_t X = 0; X < std::numeric_limits<T>::digits; X++) {
if (B & (1 << X)) {
C += (A << X);
}
}
return C;
}
#追記II
割り算を思いついたので追記です。
ただ、無学なため剰余の符号関係が解りません。
筆算法です。
code.cpp
template<class T>
int Sign(const T& A) {
return A >= 0 ? 1 : -1;
}
template<class T>
T Abs(const T& In) {
return In >= 0 ? In : -In;
}
template<class T>
std::tuple<T, T> DivMod(const T& A, const T& B) {//筆算法デス。
T Y(0);
T Z(Abs(A));
std::size_t i = 0;
if (B == 0) { return { 1,A }; }
if (Abs(A) <Abs(B)) { return { 0,A }; }
for (std::size_t j = 0; j < std::numeric_limits<T>::digits; j++) {
for (i = 0; i < std::numeric_limits<T>::digits; i++) {
if ((Abs(Z)>>i) < Abs(B)) { break; }
}
Y |= 1 << (i-1);
Z -= Abs(B) << (i-1);
if (Abs(Z) < Abs(B)) { break; }
}
return { Y * Sign(Sign(A) * Sign(B)),Abs(Z) * Sign(Sign(A) * Sign(B)) };
}