计算机是使用逻辑门电路进行计算的,逻辑门又可以封装出全加器、移位器等逻辑元件。为了更好的理解计算机内部的计算原理,我使用C++实现的对计算机内部电路的抽象表达。因为计算机进行计算的最基本的逻辑单位是各种位操作,所以我们首先使用模板封装出位操作。
模板BitBase<>,实现了加法,按位或,按位与以及左右移位(强制性一次只能移1位),抽象性的表达了硬件电路的结构。complexity是电路的复杂度,
/**
* file name: byte
*
* author: Tursom K. Ulefits
* email: tursom@foxmail.com
* qq: 737097096
* create date: 18-2-28 下午11:26
*/
#ifndef BIT_CALC_H
#define BIT_CALC_H
#include <cstdint>
namespace bit_calc {
static int complexity = 0;
static int time=0;
bool booltest(bool b) {
complexity++;
return b;
}
bool loop(bool b){
complexity++;
time++;
return b;
}
template<typename T>
class BitBase {
public:
typedef T type;
explicit BitBase(T value) : value(value) {
complexity++;
}
explicit BitBase(const BitBase *b) : value(b->value) {
complexity++;
}
T value;
T getValue() {
return value;
}
operator T() { return value; }
BitBase &operator=(BitBase);
explicit operator bool() const;
BitBase operator|(BitBase b) const;
BitBase operator&(BitBase b) const;
BitBase operator<<(int n) const;
BitBase operator>>(int n) const;
void moveLeft();
void moveRight();
BitBase operator+(BitBase BB) const;
BitBase operator~() const;
bool isPositive() const;
bool isNegative() const;
bool isZero() const;
bool notZero() const;
};
template<typename T>
bool BitBase<T>::isZero() const {
complexity++;
return !*this;
}
template<typename T>
bool BitBase<T>::isNegative() const {
complexity++;
complexity++;
complexity++;
return this->value & 1 << (sizeof(T) * 8 - 1) && value != 0;
}
template<typename T>
BitBase<T> &BitBase<T>::operator=(BitBase<T> b) {
complexity++;
this->value = b.value;
return *this;
}
template<typename T>
BitBase<T> BitBase<T>::operator|(BitBase<T> b) const {
//complexity++;
return BitBase(value | b.value);
}
template<typename T>
BitBase<T> BitBase<T>::operator&(BitBase<T> b) const {
//complexity++;
return BitBase(value & b.value);
}
template<typename T>
BitBase<T>::operator bool() const {
complexity++;
return bool(value);
}
template<typename T>
BitBase<T> BitBase<T>::operator~() const {
//complexity++;
return BitBase(~value);
}
template<typename T>
BitBase<T> BitBase<T>::operator<<(int n) const {
//complexity++;
return BitBase(value << 1);
}
template<typename T>
BitBase<T> BitBase<T>::operator>>(int n) const {
//complexity++;
return BitBase(value >> 1);
}
template<typename T>
void BitBase<T>::moveLeft() {
complexity++;
value = value << 1;
}
template<typename T>
void BitBase<T>::moveRight() {
complexity++;
value = value >> 1;
}
template<typename T>
bool BitBase<T>::isPositive() const {
complexity++;
complexity++;
complexity++;
return !(this->value & 1 << (sizeof(T) * 8 - 1)) && value != 0;
}
template<typename T>
BitBase<T> BitBase<T>::operator+(BitBase BB) const {
//complexity++;
return BitBase<T>(value + BB.value);
}
template<typename T>
bool BitBase<T>::notZero() const {
return value != 0;
}
typedef BitBase<bool> BitBool;
typedef BitBase<uint8_t> byte;
}
#define WHILE while(loop(
#define IF if(booltest(
#define THEN ))
#endif BIT_CALC_H
减法的实现就是减数取负在再加被减数,而取负操作为:
template<typename T>
BitBase<T> neg(BitBase<T> &a) {
static const BitBase<T> one(1);
a = ~a;
a = a + one;
return a;
}
乘法的实现则不是简单的暴力相加,而是类似十进制中乘法的运算,只不过二进制中乘法的实现更加方便,只需要判断每一位的0或1:
template<typename T>
BitBase<T> munt(BitBase<T> a, BitBase<T> b) {
static const BitBase<T> zero(T(0)), one(T(1));
static const BitBool True(true), False(false);
BitBool negative(false);
IF b.isNegative()THEN {
neg(b);
negative = True;
}
BitBase<T> ret(zero);
BitBase<T> zertT_test(zero);
WHILE b.notZero()THEN {
zertT_test = b & one;
IF zertT_test.notZero()THEN ret = ret + a;
a.moveLeft();
b.moveRight();
}
IF negative THEN {
neg(ret);
return ret;
} else
return ret;
}
除法操作也类似:
template<typename T>
BitBase<T> div(BitBase<T> a, BitBase<T> b) {
static const BitBase<T> zero(T(0)), one(T(1));
static const BitBool True(true), False(false);
BitBool positive(false);
BitBase<T> location(one);
BitBase<T> a1(a - b);
BitBool bool_test1(True);
BitBase<T> ret(zero);
IF b.isZero()THEN return zero;
IF b.isNegative()THEN neg(b);
else positive = True;
WHILE a1.isPositive()THEN {
b.moveLeft();
location.moveLeft();
a1 = BitBase<T>(a - b);
}
WHILE b.notZero()THEN {
a1 = BitBase<T>(a - b);
bool_test1 = BitBool(!BitBool(a1.isNegative()));
IF bool_test1 THEN {
a = BitBase<T>(a - b);
ret = ret + location;
}
location.moveRight();
b.moveRight();
}
IF positive THEN return ret;
else return neg(ret);
}
我们可以看到,2进制乘除法的实现其实完全可以使用10进制的方法,而不是暴力的靠迭代。
在这个实现中,虽然有while循环存在,但是在硬件层面上可以使用多个单元进行并行计算,从而实现操作时间常量化,也就大大减少了进行乘除法操作所需要的时间。