2008-11-03 80 views
1

檢查出來:這個小.NET控制檯程序得出了有趣的結果...注意一下,我在兩種不同的方式浮點數轉換成整數:將浮點數轉換爲整數時的.NET錯誤?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace CastVsConvert 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int newWidth = 0; 
      CalculateResizeSizes(600, 500, out newWidth); 
     } 

     static void CalculateResizeSizes(int originalWidth, int maxWidth, out int newWidth) 
     { 
      float percentage = 1.0F; 
      percentage = maxWidth/(float)originalWidth; 

      newWidth = (int)((float)originalWidth * percentage); 
      int newWidthConvert = Convert.ToInt32((float)originalWidth * percentage); 

      Console.Write("Percentage: {0}\n", percentage.ToString()); 
      Console.Write("Cast: {0}\n", newWidth.ToString()); 
      Console.Write("Convert: {0}\n", newWidthConvert.ToString()); 
     } 
    } 
} 

我希望爲「演員」的輸出和「轉換」是相同的,但它們不是...這裏是輸出:

C:\Documents and Settings\Scott\My Documents\Visual Studio 2008\Projects\CastVsC 
onvert\CastVsConvert\bin\Debug>CastVsConvert.exe 
Percentage: 0.8333333 
Cast: 499 
Convert: 500 

有誰知道爲什麼.NET這裏返回的值不同?

回答

5

演員在轉換四捨五入期間將小數點後面的數字部分截斷。

14

它不是一個bug,cast截斷,convert輪。

this

5

從文檔爲Convert.ToInt32返回值:

四捨五入到最接近的32位有符號整數。如果兩個整數之間的值爲一半 ,則返回偶數 ;也就是說,4.5 轉換爲4,和5.5被轉換 至6

鑄造不圍捕 - 它只是截斷。乘法的結果是在500以下,所以鑄造將截斷爲499,而Convert.ToInt32將它舍入到500.

1

有一個額外的,隱藏的轉換可能導致這種情況。例如,如果使用此代替重新計算:

int newWidthConvert = Convert.ToInt32(newWidth); 

您將得到相同的結果。

public static int ToInt32(float value) 
{ 
    return ToInt32((double) value); 
} 

有一個隱藏的投給Double:當您使用反射在Convert.ToInt32(float)偷看發生了什麼事變得更加清晰。

如果您添加幾行的調查,然後使用調試器來看看,你看看會發生什麼:

float newWidth1 = ((float)originalWidth * percentage); 
double newWidth2 = ((float)originalWidth * percentage); 

double更精確和保存價值499.999999和幾個更多的小數位數。 float不太精確,存儲500.0。整數轉換會截斷小數部分,所以基於中間轉換的結果是500或499。當您撥打Convert.ToInt32()時,結果已經轉換爲float,因此您可以獲得500.0的Double表示形式。就我個人而言,我更喜歡總是使用double