2013-10-17 62 views
7

之間的表達式如果我有以下表達式:隱式轉換/促銷浮動的或雙在C#和Java

byte A = 69; 
int B = 123; 
long C =; 
float D = 4.9f; 
double E = 11.11; 

double X = (B * 100) + 338.1 - (E/B)/C; 
double X1 = (B * 100) + (A * D) - (E/B)/C; 

// JAVA - lost precision 
System.out.println(X); // 12638.099971861307 
System.out.println(X1); // 12638.099581236307 

// C# - almost the same 
Console.WriteLine(X); // 12638.0999718613 
Console.WriteLine(X1) // 12638.0999784417 

我注意到,爪哇失去從X精度其中338.1是隱式的雙而C#幾乎不。我不明白爲什麼,因爲338.1在float和double中是等於的。點後只有一個數字。

+1

338.1在float和double中是不相同的。 338.1的確切二進制擴展是永久重複的,所以當表達爲雙精度時,它的整數非零數字多於浮點數。 –

+1

請閱讀http://csharpindepth.com/Articles/General/FloatingPoint.aspx – Rohit

回答

1

在Java中,(B * 100) + (A * D)將是一個浮點數;這將是最接近12638.1的浮動。但是,12638需要14位數字以二進制表示,包括最初的1;這留下有效數字的10位數字來表示小數部分。因此,你將得到最接近1024的數字爲0.1 - 這是102/1024。原來這是0.099609375 - 所以浮點數的舍入誤差爲0.000390625。

這似乎是你在Java程序中獲得的X和X1之間的區別。

恐怕我不是C#專家,所以我不能告訴你爲什麼C#是不同的。

0

這與編譯器對您的表達式的解釋有關。由於您沒有指定任何中間類型轉換,因此編譯器會執行A * D作爲第一種類型轉換,然後執行乘法,而不是您期望的反轉。這可能看起來像一個奇怪的結果,但它是編譯器給你一個更精確的結果的一種方式,而不必指定繁瑣的類型轉換。

Java不處理這個給你,所以(B * 100) + (A * D)intfloat的乘法 - 導致float。這可以在C#來模擬這樣的:

double X2 = (float)((B * 100) + (A * D)) - (E/B)/C; 
Console.WriteLine("X2: {0}", X2); 

這是優勢(或DIS-優勢一些可能會說)的高級編譯器之一。