int a = (int)(19.9 *100); //19.9預設是double類型
int b = (int)(19.9M *100 ); //將19.9轉換成decimal類型
Console.WriteLine(a); //輸出:1989
Console.WriteLine(b); //輸出:1990
不用說.NET,C#,就是用Java來幹估計也是這個結果,這個結果具有必然性.
19.9 作為 Double 類型表示,二進位形式是:
1 00000000110 011111001100110011001100110011001100110011001100110
(注意中間的兩個空格,如果你不知道啥意思,就去查查double的記憶體表示形式吧)
但是19.9 * 100 由於是二進位運算的結果是
1 00000010011 111000101111111111111111111111111111111111111111111
由於後面有n個11111所以我猜測可能發生了溢出被電腦捨去了.
於是這個數字比 1990少那麼一點點(可能是 1989.99999999...)
但是你的取整操作卻直接截斷了後面的數字,於是成了1989
至於你說9.9 29.9為什麼不那樣,那就是可能沒有發生溢出了(不要以10進位的思維來猜測二進位)
別的語言你只能通過保留更高的精度並且四捨五入來實現,而C#為了支援金融運算,獨家引入變態的Decimal類型,於是你的問題現在可以通過decimal解決了(decimal的精度非常高,大約有好幾十層樓那麼高吧...夠用了)
二進位無法精確表示浮點數,小數部分一般都是用近似值來標示的。所以19.9*100的二進位標示會有那麼多的11111111。而(int)(19.999999999)結果是直接截斷小數點後面的結果,所以1989.999999也就是1989了。但是decimal為什麼能正確呢,因為它根本就不存在真正的小數儲存進位,所有的數都在小數點的右邊。那它又是如何儲存小數的呢,答案就是比例因素。當然還有符號位。