在C++中,將任何浮點值(float)轉換爲fixed point(int,16:16或24:8)的通用方法是什麼?將浮點轉換爲定點
編輯:爲了澄清,定點值有兩個部分:整數部分和小數部分。整數部分可以用有符號或無符號整數數據類型表示。小數部分由無符號數據整數數據類型表示。
爲了清楚起見,我們用錢比喻一下。小數部分可能代表美分 - 美元的一小部分。 「美分」數據類型的範圍應該是0到99.如果一個8位無符號整數用於定點數學,那麼小數部分將被分成256個均勻可分的部分。
我希望能夠解決問題。
在C++中,將任何浮點值(float)轉換爲fixed point(int,16:16或24:8)的通用方法是什麼?將浮點轉換爲定點
編輯:爲了澄清,定點值有兩個部分:整數部分和小數部分。整數部分可以用有符號或無符號整數數據類型表示。小數部分由無符號數據整數數據類型表示。
爲了清楚起見,我們用錢比喻一下。小數部分可能代表美分 - 美元的一小部分。 「美分」數據類型的範圍應該是0到99.如果一個8位無符號整數用於定點數學,那麼小數部分將被分成256個均勻可分的部分。
我希望能夠解決問題。
在這裏你去:
// A signed fixed-point 16:16 class
class FixedPoint_16_16
{
short intPart;
unsigned short fracPart;
public:
FixedPoint_16_16(double d)
{
*this = d; // calls operator=
}
FixedPoint_16_16& operator=(double d)
{
intPart = static_cast<short>(d);
fracPart = static_cast<unsigned short>
(numeric_limits<unsigned short> + 1.0)*d);
return *this;
}
// Other operators can be defined here
};
編輯:下面是基於anothercommon的方式來處理定點數(和KPexEA指出)一個更一般的類:
template <class BaseType, size_t FracDigits>
class fixed_point
{
const static BaseType factor = 1 << FracDigits;
BaseType data;
public:
fixed_point(double d)
{
*this = d; // calls operator=
}
fixed_point& operator=(double d)
{
data = static_cast<BaseType>(d*factor);
return *this;
}
BaseType raw_data() const
{
return data;
}
// Other operators can be defined here
};
fixed_point<int, 8> fp1; // Will be signed 24:8 (if int is 32-bits)
fixed_point<unsigned int, 16> fp1; // Will be unsigned 16:16 (if int is 32-bits)
這對於將浮點數轉換爲整數很合適,但OP也希望得到fixed point。我不知道(C++不是我可以輕易想到的東西)。在C++中,如何做到這一點,我不知道(C++並不是我能想到的東西)。也許可以嘗試縮放整數方法,即使用32位或64位整數,並以編程方式將最後的6位數字分配給小數點右側的內容。
從浮點數轉換爲整數會丟棄小數部分,所以如果你想保留這個小數部分作爲固定點,那麼你只需在浮點數之前乘以浮點數就可以了。下面的代碼不會檢查你的溢出。
如果你想要16:16
double f = 1.2345;
int n;
n=(int)(f*65536);
如果你想24:8
double f = 1.2345;
int n;
n=(int)(f*256);
沒有任何內置在支持C++的點數。你最好的選擇是編寫一個包裝器'FixedInt',它需要雙打併轉換它們。
至於通用的方法轉換... int部分很容易,只需抓住值的整數部分,並將其存儲在高位...小數部分將沿着以下幾行:
for (int i = 1; i <= precision; i++)
{
if (decimal_part > 1.f/(float)(i + 1)
{
decimal_part -= 1.f/(float)(i + 1);
fixint_value |= (1 << precision - i);
}
}
雖然這很可能包含bug仍然
****編輯**:我的第一個意見適用於凱文的編輯之前,但我會離開這裏爲後人。答案有時會在這裏很快改變!
凱文的方法的問題是,與固定點你通常打包成一個保證字大小(通常32位)。分別聲明這兩個部分會讓您感受到編譯器結構打包的奇思妙想。是的,你可以強制它,但它不適用於16:16表示以外的任何其他功能。
KPexEA通過將所有內容打包成int來更接近標記 - 儘管我會使用「signed long」來試圖在32位上進行顯式指定。然後,您可以使用他的方法來生成定點值,並且位切片會再次提取組件部分。他的建議還包括24:8的情況。
(和其他人誰建議剛的static_cast .....你在想什麼;?))
我給這個問題的答案寫的最好的答案的傢伙,但我真的使用的相關問題代碼那點here。
它使用了模板,並且很容易依賴於boost lib。
如果您使用Visual C++,在考慮將所有浮點重構爲固定點之前,先試驗`/ fp:fast`開關。這個浮點模型開關允許優化,這可以允許浮點輕鬆地跳動固定點的速度。絕對是一個低估的功能。 – 2015-12-30 17:24:01