這段時間在學習DSP浮點運算轉定點運算過程中,在網上看到了一位網友給出的一段程式.如下所示:
---------------------------------------------------------
聲明:
此文為原創,歡迎轉載,轉載請保留如下資訊
作者:聶飛(afreez) 北京-中關村
連絡方式:afreez@sina.com (歡迎與作者交流)
初次發布時間:2006-11-28
不經本人同意,不得用語商業或贏利性質目的,否則,作者有權追究相關責任!
---------------------------------------------------------
/***************************************************************
// 將32位浮點數fval轉換為32位整數並儲存在ival中
// 小數部分將被裁剪掉
//
void TruncToInt32 (int &ival, float fval)
{
ival = *(int *)&fval;
// 提取尾數
// 注意實際的尾數前面還有一個被省略掉的1
int mantissa = (ival & 0x07fffff) | 0x800000;
// 提取指數
// 以23分界,指數大於23則左移,否則右移
// 由於指數用位移表示,所以23+127=150
int exponent = 150 - ((ival >> 23) & 0xff);
if (exponent < 0)
ival = (mantissa << -exponent);
else
ival = (mantissa >> exponent);
// 如果小於0,則將結果取反
if ((*(int *)&fval) & 0x80000000)
ival = -ival;
}
*******************************************************/
程式流程寫的很清晰.興奮之餘馬上在自己的機器上測試了一把,結果發現總是不正確,大體如下:
//主函數
...
int ival;
float fval=4.23;
TruncToInt32 (&ival, fval);
//這裡的輸出結果不正確
printf("ival=%d/n",ival);
...
//函數定義
void TruncToInt32 (int &ival, float fval)
{
//skip
...
// 如果小於0,則將結果取反
if ((*(int *)&fval) & 0x80000000)
ival = -ival;
//發現在這裡輸出的結果是正確的
printf("ival=%d/n",ival);
}
仔細看了一眼,才發現,原來是函數調用時參數傳遞有問題。主要上理解指標和指標的指標,大家對照我的思路考慮考慮吧。
修改主程式,如下所示:
...
int ival;
float fval=4.23;
RightTruncToInt32 (&ival, fval);//第n行,假定是經過修正後的函數
ival=(int)fval;//第n+1行
printf("ival=%d/n",ival);
...
對n行和n+1行進行時間效率測試,顯示,第n+1行所需的計算時間少於第n行。
對主程式進一步改善,大致如下:
...
int ival;
float fval=4.23;
//-------Begin more fast section?-----------
// 提取尾數
int ival= ((*(int *)(&fval)) & 0x07fffff) | 0x800000;
// 提取指數
int exponent = 150 - (((*(int *)(&fval)) >> 23) & 0xff);
if (exponent < 0)
ival = (ival<< -exponent);
else
ival = (ival >> exponent);
// 如果小於0,則將結果取反
if ((*(int *)&fval) & 0x80000000)
ival = -ival;
//-------End more fast section?-----------
ival=(int)fval;//第n+1行
...
結果顯示,在RedHat 9.0平台上測試顯示,如果編譯不加最佳化選項,more fast section的執行時間效率優與第n+1行;加最佳化選項,第n+1行的執行時間效率優與more fast section。
分析結論:
由於more fast section還有一些程式碼可以最佳化,我想,在一些特定場合下,還是可以借鑒這個思路的。