2014-10-11 28 views
4

當使用數學運算時,我有一個關於在基值類型之間轉換的常見問題。 Microsoft C#規範中是否有書面規則?我找不到它們。它在Mono中的工作原理是否相同?當在C#中需要基值類型的轉換時

例子:

double a = 1/1234;     //Result is 0 
double b = 1.0/1234;     //Result is 0,000810372771474878 
double c = 1.0/(double)1234;   //Result is 0,000810372771474878 
double d = (double)1/(double)1234; //Result is 0,000810372771474878 
double e = 1/1234.0;     //Result is 0,000810372771474878 

我可以假設,結果始終是一個雙重當股息或除數雙打? 或者由於某種原因,是它更好地保證兩者都是雙打(見案例d - 我見過很多這樣的代碼,這實際上讓我問這個問題)

問候, 塞巴斯蒂安

回答

4

長話短說,是的,它是安全的假設,編譯器將假定double當二元運算的至少一側的類型爲這一點。你不需要明確(雖然當然有些時候,從可讀性的角度來看它可能是有用的,但這並不重要)。

只是要清楚,雖然我不認爲你在原始問題中有這種困惑,但是你分配結果的變量類型對如何確定除法運算符過載沒有影響。

您的首要案例只是簡單地使用隱式轉換,這將有明確的等價物。

double a = (double)(1/1234); 

,你把它分配給一個double不影響事實的事實1/1234求值,因爲你已經發現,以0,因爲鑄發生事實上的崗位分工。如果我們在這裏的時空中挖洞,這個例子將落在本文底部列表的最後一個例子中,其中兩個整數被分開。因此,根據規範的第7.8.2節,這將返回商的底線或0


此行爲在C#5規範的第7.3.6節(它花了一點看,我承認)中描述,重點是我的。

7.3.6數字優惠

...

當重載決策規則(第7.5.3節)被施加到該組操作符,其效果是選擇第一操作員的對於這些操作數類型存在隱式轉換。例如,對於操作b * s,其中b是一個字節並且s是一個短的,重載決議選擇運算符*(int,int)作爲最佳運算符。因此,效果是b和s被轉換爲int,並且結果的類型是int。 同樣,對於操作i * d,其中i是一個int並且d是一個double,重載決議選擇運算符*(double,double)作爲最佳運算符。

這當然不僅適用於乘法,如其例子所示,而且適用於任何二元運算。

只是爲了好的措施,層次如下,取自7.3.6.2,重點仍是我的。

•如果其中一個操作數是十進制類型,另一個操作數轉換爲十進制類型,或者如果另一個操作數的類型爲float或double,則會發生綁定時錯誤。
否則,如果任一操作數的類型爲double,則另一個操作數轉換爲double類型。
•否則,如果任一操作數的類型爲float,則另一個操作數轉換爲float類型。
•否則,如果其中一個操作數是ulong類型,另一個操作數將轉換爲ulong類型,或者如果另一個操作數的類型爲sbyte,short,int或long,則會發生綁定時錯誤。
•否則,如果任一操作數的類型爲long,則另一個操作數將轉換爲long類型。
•否則,如果其中一個操作數的類型爲uint,另一個操作數的類型爲sbyte,short或int,則兩個操作數都轉換爲long類型。
•否則,如果任一操作數的類型爲uint,則另一個操作數轉換爲uint類型。
•否則,兩個操作數都轉換爲int類型。

在現實中,編譯器實際上執行該投給你,通過使非double操作數爲double類型。

1

當你把兩個整型你會得到一個整數結果。因爲int無法保存0,000810372771474878結果將被截斷爲0然後0(int)轉換爲double,因此得到0.0

爲了得到浮點結果的操作數之一應該是一個浮點type.In這種情況下,整型操作數將被轉換成double/floatdecimal,這取決於你的電話號碼的類型。

有關於劃分運營商的詳細信息C# Specification 7.7.2 Division operator