咱們經過簡單的代碼試驗一下:code
int newWidth, newHeight; GetThumbnailSize(200, 200, 100, 100, out newWidth, out newHeight); Console.WriteLine("{0}, {1}", newWidth, newHeight); GetThumbnailSize(300, 300, 100, 100, out newWidth, out newHeight); Console.WriteLine("{0}, {1}", newWidth, newHeight);
獲得的結果是:orm
100, 100 99, 100
第一個結果天然沒有問題,可是在第二個結果中爲何是99而不是100?爲此,咱們再經過如下的代碼來觀察一番:ci
ratio: 0.3333333333333333333333333333 new value: 99.99999999999999999999999999 to int: 99
可見,雖然使用了decimal,精度已經很是高的,可是在通過了一除一乘,它仍是沒有恢復到最精確值。雖然一直說要注意浮點數計算時的精度問題,可是對於這個問題許多朋友每每只是理解到「不能直接兩個浮點數相等」,包括我本身的第一印象。但事實上,從上面的結果也能夠看出,把一個浮點數直接轉換成整形,它即是使用了「去尾」而不是「四捨五入」的方法。所以,雖然newValue的值無比接近100,可是在強制去尾後它仍是變成了99。編譯器
若是要在原來的方法中改變這個問題,最簡單的方法多是把最後的強制轉型替換成Math.Round方法。Math.Round方法使用四捨五入,應該可以解決問題。不過若是隻是這樣的話收穫不大,咱們再仔細想一想,應該如何作到儘量的精確。it
兩個浮點數相除可能會喪失精度,但若是是乘法操做,在通常狀況下精度是不會丟失的,除非發生了溢出的話,或者小數位數太多。所以在計算過程當中爲了保持精度,咱們應該儘量的作乘法,而不是做除法。例如如下的判斷:io
if ((decimal)desiredWidth / originalWidth < (decimal)desiredHeight / originalHeight)
其實最好改寫成「等價」的乘法操做。編譯