[英]Floating point evaluation order in C
我在Windows 7上使用Code :: Blocks 10.05。
我已經編譯了以下程序,
#include<stdio.h>
int main()
{
float f=1.5;
printf("%f\n",(f-1)*1/2);
return 0;
}
輸出為0.250000 。 我了解如下
由於f
是浮點數(f-1)
返回的浮點數為0.500000 ,整個表達式被升級為浮點算術,因此1/2也被視為浮點數,從而得到0.500000 ,從而得到結果。
還有下面的陳述,
float f=1.5;
printf("%f\n",1/2*(f-1));
給出了0.000000作為答案。 在這里,表達式1/2
執行整數除法。 在這里,我希望首先評估(f-1)
並將整個表達式升級為浮點運算。
我再次想起,因為波蘭記號是
* / 1 2 - f 1
除法是執行的第一個操作,因此是結果。 我對這個假設是否正確?
最后,以下語句違反了所有邏輯:
float f=1.5;
printf("%f\n",(f-1)*(1/2));
輸出為0.000000 ,但波蘭符號為,
* - f 1 / 1 2
因此(f-1)
應該首先被求值,因此整個表達式將升級為浮點運算,並且輸出應為0.250000 。
我哪里做錯了? 這與運算符*的評估順序有關嗎? C語言中的表達是否模棱兩可?
由於f是浮點數(f-1)返回的浮點值為0.500000且整個表達式被升級為浮點運算
不,您從哪里得到錯誤信息? 晉升為浮點數僅適用於其中一個操作數均為浮點數的一個運算符。 1/2
不被視為浮點表達式-這樣,甚至不對其進行求值。 由於乘法和除法的優先級相同,並且是左聯想的,
(f - 1) * 1 / 2
被評估為
((f - 1) * 1) / 2)
並且,將1
提升為float
(至少),然后因為((f - 1) * 1)
也是浮點數,因此除法的另一個操作數也將2
提升為float
(或更高的float
精度FP編號,具體取決於編譯器的要求)。
在這里,我希望首先評估(f-1)並將整個表達式升級為浮點運算。
不,正如我剛才解釋的那樣,這是一個錯誤的期望。 它不是要轉換為浮點數的完整表達式。 它只是運算符的另一個立即操作數,其中一個操作數是float
。 因此在表達式中:
(f - 1) * (1 / 2)
f - 1
是float
。 1 / 2
是一個整數,它是零,然后將整數零提升為float
因為*
的另一個操作數是float
。 /
的操作數是整數,因此除法是根據整數算術規則進行的。
*
和/
具有相同的優先級,因此(f-1)*1/2
等於((f-1)*1)/2
,而不是您認為的那樣。
1/2*(f-1)
等於(1/2)*(f-1)
,其中1/2
的值為0
。
由於偏癱: (1/2)
您只會得到一個大的零(1/2的結果)升級為浮點數。 因此結果為零。
(1/2)
被視為整數,結果為零。 與零超前相乘的結果也為零。
該表達式從左到右求值:
f
是float
。 f - 1
兩個操作數都提升為double
,值是0.5
。 調用表達式E1
。 (f - 1) * 1
,即E1 * 1
,兩個操作數均提升為double
並且表達式的值為0.5
。 調用表達式E2
。 (f - 1) * 1 / 2
相同,即E2 / 2
,兩個操作數均提升為double
,th表達的值為0.25
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.