這個實現的主要目的是在不改變源代碼的邏輯的前提下,只用FixedNum這個類去替換float的定義來實現浮點數轉定點數的優化
#define FNSHIFT 16 //之所以不用const int 是怕編譯器沒那麼智能,不是每個編譯器都有VC那麼“標準”
class FixedNum//定點數
{
public:
FixedNum()
{
num = 0;
}
explicit FixedNum(const float& r)
{
num = r * (1<<FNSHIFT);
}
void operator=(const float& r)
{
num = r * (1<<FNSHIFT);
}
void operator=(const int& r)
{
num = r<<FNSHIFT;
}
FixedNum operator+(const FixedNum& r)
{
FixedNum nfn;
nfn.num = num + r.num;
return nfn;
}
operator float()
{
return ((float)num) / (1<<FNSHIFT);
}
bool operator==(const float r)
{
return ((float)num) / (1<<FNSHIFT) == r;
}
float operator-(const float r)
{
return ((float)num) / (1<<FNSHIFT) - r;
}
float operator/(const float r)
{
return ((float)num) / (1<<FNSHIFT) / r;
}
float operator*(const float r)
{
return r * num / (1<<FNSHIFT);
}
float operator*(const int r)
{
return ((float)r) * num / (1<<FNSHIFT);
}
FixedNum operator*(const FixedNum& r)
{
FixedNum nfn;
nfn.num = (num>>(FNSHIFT/2)) * (r.num>>(FNSHIFT/2));
return nfn;
}
void operator+=(const FixedNum& r)
{
num+=r.num;
}
private:
int num;
};
比較值得注意的是拷貝構造函數前面的explicit這個關鍵字,用來防止在不小心的情況下將FixedNum隱性轉換成了float
如果不這個關鍵字,那麼在處理乘號這個操作符的時候當左右兩邊都是FixedNum類型時,會編譯出錯,編譯器不知道該用FixedNum*FixedNum還是FixedNum*float
雖然C++重載操作符的特性被很多大牛罵個狗血淋頭,但偶爾的小範圍應用還是能不錯的提高效率,存在即合理嘛