新手陷阱 · 整數運算

為什麼 C# 裡 7 / 2 = 3?

這不是 bug 也不是四捨五入。當 / 兩邊都是整數時,C# 執行整數除法:算出 3.5 然後把小數扔掉。這裡的每一段程式碼都能現場執行——自己驗證。

Console.WriteLine(7 / 2);          // int / int   → int  (3)
Console.WriteLine(7 / 2.0);        // int / double → double
Console.WriteLine(7.0 / 2);        // double / int → double

規則:只要任意一邊是 double,另一邊就被提升,結果保留小數。如果兩邊都是整數(int、long、short……),結果是整數,小數部分被丟棄——永遠向零截斷,不是"四捨五入"。

藏在變數裡的版本(真正咬人的那個)

字面量的情況很明顯。bug 出現在 double 藏在變數的宣告型別裡:

int a = 7;
Console.WriteLine(a / 2);      // a 是 int → 整數除法 → 3

double x = 7;                  // 同樣的值,不同的型別
Console.WriteLine(x / 2);      // 現在 double / int → 3.5

這就是"我的測試裡用 7 / 2.0 明明沒問題,換上使用者輸入就錯了"的由來:Console.ReadLine() 給你的是 string,而你一旦 int.Parse 它,下游的一切都進了整數運算。

是截斷不是四捨五入——負數向零

Console.WriteLine(7 / 2);    //  3.5 →  3  (小數直接丟棄)
Console.WriteLine(-7 / 2);   // -3.5 → -3  (向零,不是向 -4!)
Console.WriteLine(9 / 2);    //  4.5 →  4
Console.WriteLine(-9 / 2);   // -4.5 → -4

C# 向零截斷。如果你真想四捨五入,明確說出來:

Console.WriteLine(Math.Round(7 / 2.0));   // 3.5 → 4  (銀行家舍入)
Console.WriteLine((int)Math.Ceiling(7 / 2.0)); // 永遠向上 → 4

三種修法

修法一:把一邊變成 double(最地道)

int a = 7, b = 2;
double result = a / (double)b;
Console.WriteLine(result);

一邊轉就夠了——提升會傳遍整個表示式。a / (double)b 和 (double)a / b 都行。

修法二:乘個 1.0(快糙猛)

int a = 7, b = 2;
Console.WriteLine(1.0 * a / b);   // 1.0 * a 是 double → 全部提升

修法三:變數一開始就宣告成 double

如果這些值本來就該有小數(價格、平均值、測量值),它們大概應該是 double:

double a = 7, b = 2;
Console.WriteLine(a / b);

關聯陷阱:% 的符號跟著被除數走

取餘運算子遵循同一套整數規則,而且結果符號跟隨被除數:

Console.WriteLine(7 % 3);    //  1
Console.WriteLine(-7 % 3);   // -1  (符號跟 -7)
Console.WriteLine(7 % -3);   //  1  (符號跟 7)

什麼時候整數除法恰好就是你想要的

它不是設計缺陷——它正是你分頁、分桶、分組的方式:

int totalItems = 98;
int pageSize = 10;

int fullPages = totalItems / pageSize;      // 9 整頁
int lastPageItems = totalItems % pageSize;  // 8 個零頭
Console.WriteLine((fullPages + (lastPageItems > 0 ? 1 : 0)) + " pages total");
Console.WriteLine(pageSize);

相關閱讀:把 double 賦給 int 時悄悄吃掉小數的那個轉換,是錯誤 CS0029 / CS0266。去練習場試試 int x = 3.5;,看看編譯器怎麼說。