[英]Different Truncation Results When Casting
我在預測我的C代碼將如何截斷結果時遇到一些困難。 請參閱以下內容:
float fa,fb,fc;
short ia,ib;
fa=160
fb=0.9;
fc=fa*fb;
ia=(short)fc;
ib=(short)(fa*fb);
結果是ia = 144,ib = 143。
我可以理解這兩種結果的推理,但我不明白為什么這兩種計算的處理方式不同。 任何人都可以推薦我這個行為的定義或解釋差異?
編輯:結果使用英特爾酷睿i3-330m上的MS Visual C ++ Express 2010進行編譯。 我在同一台機器上的Virtual Box下的gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5)上得到了相同的結果。
允許編譯器對fa*fb
這樣的子表達使用比分配給像fc
這樣的float
變量時使用的精度更高的精度。 所以它是fc=
part,它會稍微改變結果(然后發生在整數截斷中產生差異)。
aschepler解釋了正在發生的事情的機制,但是你的代碼的基本問題是使用一個值,該值在代碼中不作為float
存在 ,它以不穩定的方式依賴於其近似值。 如果你想乘以0.9(實際數字0.9 = 0.9f
,而不是浮點值0.9
或0.9f
),你應該乘以9然后除以10,或者忘記浮點類型並使用十進制算術庫。
解決問題的一種廉價而骯臟的方法,就像你的例子中的不穩定點被隔離一樣,只是添加一個值(通常為0.5),你知道它將大於錯誤但小於之前的下一個整數的差值截斷。
這取決於編譯器。 在我的(gcc 4.4.3)中,它為兩個表達式產生相同的結果,即-144,可能是因為相同的表達式被優化掉了。
其他人解釋了發生的事情。 換句話說,我會說差異可能是因為你的編譯器在執行乘法之前在內部將浮點數提升到80位fpu寄存器,然后轉換回float或short。
如果你寫ib = (short)(float)(fa * fb);
我的假設是真的ib = (short)(float)(fa * fb);
你應該得到與將fc轉換為short時相同的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.