程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> VC++中的一個不足及其改善方法

VC++中的一個不足及其改善方法

編輯:關於C++

使用C語言編程序,有時需要把一種數值(如float類型的數值)轉換成另一種類型(如int類型)的數值使用,這時,我們就要用到類型強制轉換運算符,如(int)、(float)等。但是在VC++中,當把一個float類型的數值轉換成int類型時,有時會出現比較大的誤差。我在工作過程中就碰到過,當我把一個值為1140.00的float型變量ftemp使用如下方法轉換成int類型,

itemp=(int)ftemp;

這時,int型變量itemp的值為1139,誤差1(在本文中,我稱這種誤差為"1誤差")。這麼大的誤差,我們是不能接受的。

經過深入的測試研究,我發現:在VC++中,當一個float型變量初始化(從屏幕輸入一值,或把一常量值賦給它)後就用以上方法轉換成int類型,結果是小數部分去掉,整數部分保留,誤差小於1,沒有"1誤差";而當一個float型變量初始化後,又經過一些運算,再轉換成int類型,就可能會有"1誤差",就是說,結果不但把小數部分去掉,整數部分也可能有改變。例如,我們把以米為單位的數據轉化成以厘米為單位的數據,用float型變量f存放以米為單位的數據,用int型變量i存放以厘米為單位的數據,使用下面語句實現數據轉換。

i=(int)(f*100);

當f=11.40(米)時,i=1139(厘米);

當f=11.41(米)時,i=1140(厘米);

當f=12.32(米)時,i=1231(厘米);

當f=12.33(米)時,i=1232(厘米);

等等,很多數據的轉換存在著"1誤差"。

不過,大部分數據的轉換是沒有誤差的,如當f=11.39(米)時,i=1139(厘米);

當f=12.31(米)時,i=1231(厘米)。

如果改用以下方法實現數據轉換,"1誤差"一樣存在。

float ftemp;
ftemp=f*100;
i=(int)ftemp;

這裡,ftemp是一局部變量(函數內定義)或全局變量(函數外定義)。把f*100改成f*100.0,"1誤差"也存在。但是如果把ftemp改成為類的屬性變量(在類裡定義),"1誤差"就不存在。

我還發現,"1誤差"現象對正負數具有對稱性。就是說,如果有"1誤差",對於正數,(int)轉換後少了1;對於負數,(int)轉換後多了1。如上例子中,當f=-11.40(米)時,i=-1139(厘米);當f=-11.41(米)時,i=-1140(厘米);當f=-12.32(米)時,i=-1231(厘米);當f=-12.33(米)時,i=-1232(厘米)。而且,轉換誤差不會大於1。

針對以上分析結果,我在這裡給出一個校正"1誤差"的方法,以供參考。我設計了一個把float型數轉換成int型數的函數,用以代替(int)運算符。函數清單如下:

int float_to_int(float f)
{
int i;
float ferror;
i=(int)f;
ferror=f-(float)i;
if(fabs(ferror)>0.99) //有"1誤差",校正
if(f>0)
i++;
else
i--;
return(i);
}

在此函數中,通過判斷(int)類型轉換前後的誤差ferror是否大於0.99來判斷是否有"1誤差",如果有,就進行校正。校正方法是,對於正數,把(int)轉換結果加1;對於負數,把(int)轉換結果減1。

定義了float_to_int()函數後,用它代替(int)運算符就能校正"1誤差"了。如對上面把以米為單位的數據轉化成以厘米為單位的數據這一例子來說,改成

i=float_to_int(f*100);

float ftemp;
ftemp=f*100;
i=float_to_int(ftemp);

當f=11.40(米)時,i=1140(厘米);

當f=11.41(米)時,i=1141(厘米);

當f=12.32(米)時,i=1232(厘米);

當f=12.33(米)時,i=1233(厘米);

當f=-11.40(米)時,i=-1140(厘米);

當f=-11.41(米)時,i=-1141(厘米);

當f=-12.32(米)時,i=-1232(厘米);

當f=-12.33(米)時,i=-1233(厘米)。

"1誤差"沒有了。而且對原來沒有"1誤差"的數據也沒有影響,如當f=11.39(米)時,i=1139(厘米)。

通過對大量的數據進行測試檢查,證明此方法是有效的。

另外,對於double型轉換成int型,也有類似的"1誤差"問題,只是出現誤差的數據比較少,而且還有偶然性(就是,對於某個數值,有時候有"1誤差",有時候又沒有"1誤差")。應用類似的方法也可以把double型轉換成int型的"1誤差"校正過來。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved