2009-09-06 94 views
3

求索爲C#和Java以下,C#和Java:3/2 * 3.2 = 3.2,爲什麼?

double d = 3/2 * 3.2; 

的Java

System.out.println(d); // 3.2 

C#

Console.WriteLine(d); //3.2 

它跳過3/2,

我們知道正確答案應該是4.8

如果我改變

double d = 3.00/2 * 3.2; 

我可以得到4.8,

所以我要問,如果(3/2 * 3.2)是非法的,爲什麼Eclipse和VS2008有沒有錯誤? 如何在C#和Java中防止這個問題?

回答

11

3/2被認爲是一個整數除法,所以結果是1

然後,執行13.2之間的乘法會導致整數1晉升爲浮點1,導致3.2

的理念是:

// Both "3" and "2" are integers, so integer division is performed. 
3/2 == 1 

// "3.2" is a floating point value, while "1" is an integer, so "1" is 
// promoted to an floating point value. 
1 * 3.2 --> 1.0 * 3.2 == 3.2 

當輸入2.0,小數點告訴Java來考慮面值作爲浮點值(在這種情況下,double),這樣計算的結果是4.8如預期。沒有小數點,該值是一個整數文字。

這不是一個錯誤,而是文字如何處理的問題。

以下鏈接有更多的信息:

25

3/2是Integer分區,其結果是1

1 * 3.2等於3.2,這是您收到的結果。

這是一個定義良好的公式,它具有定義良好的預期結果,因此編譯器不會出錯。使用3.00,這是強制編譯器使用浮點數學的最直接的方法。

Thorbjørn的回答:另一種選擇是通過以1.0*開始標準化所有的浮點計算,在您的示例中它將是1.0*3/2*3.2

+1

乘法交際與分工,不管你使用的「真正的」數學或沒有。它在任何地方都沒有更高的優先級。 – 2009-09-06 12:24:03

+0

-1:此計算中的操作通常是從左到右計算的。請參閱:http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B – 2009-09-06 12:26:50

+0

我認爲這裏的混淆來自乘法通常出現在代數分子或分母內的事實。或者PEMDAS。 – snarf 2009-09-06 12:27:37

3

將一個整數文字與另一個整數文字分開時,整個表達式將按整數除法處理:3/2因此變爲1;不是1.5(因爲它都是整數)。直到下一部分,1 * 3.2是整數提升到一個double;因此,直到這一點它實際上變成了1.0

編輯:沒有錯誤標記,因爲它不是非法的。

1

3/2是第一次執行的操作。

32是整數。當兩個int被劃分時,答案是int(在這種情況下,答案是1)。

因此從3/2 * 3.2你最終1 * 3.2。當您乘以intfloat時,結果將被提升爲float。所以答案是3.2

1

這是由於鑄造和數字類型問題。

在C#(和Java,因爲它似乎太)3和2都是整數值,以便分割「3/2」是一個整數除法這導致整數1

由於3.2是一個浮點值的除法的整數結果轉換爲浮點值並在此之後進行乘法運算,因爲1 * 3.2是3.2的結果。

這裏沒有代碼錯誤,所以這就是爲什麼Java和C#接受這個。

最安全的方法將總是告訴你需要使用

3.0/2.0 * 3.2

這適用於所有情況在這裏浮點值的編譯器。

7

這是完全合法的,但3/2是一個整數除法(就像做了除法,但是選擇了最接近0的數字(在某些語言中爲無​​窮大))。你需要給編譯器一些「提示」你想要做的事情。

您只需編寫

3.0/2 * 3.2   or  3/2.0 * 3.2 
3.0/2.0 * 3.2 
3d/2d * 3.2 (C#) 
(double)3/2 * 3.2 
6

避免它。如果你想成爲肯定的是,計算情況與小數而不是整數,然後要麼開始

1.0 * 3/2 * 3.2 

或者告訴編譯器第一個數字是一個實數/雙精度:

3d/2 * 3.2 
+0

+1從1.0 , 很乾淨 – 2009-09-06 12:39:45

0

在C#中

3d/2d * 3.2 

如前所述之前