MidpointRounding.ToEven ใช้กับ decimal.Round() และ Math.Round() เพื่อปัดเศษแบบ Banker's Rounding (Round Half to Even) - มาตรฐาน IEEE 754
Banker's Rounding คืออะไร
เมื่อค่าอยู่ตรงกลาง (x.5) จะปัดไปยังเลขคู่ที่ใกล้ที่สุด:
| ค่า | AwayFromZero | ToEven (Banker's) |
|---|---|---|
| 1.5 | 2 | 2 |
| 2.5 | 3 | 2 |
| 3.5 | 4 | 4 |
| 4.5 | 5 | 4 |
| -1.5 | -2 | -2 |
| -2.5 | -3 | -2 |
ตัวอย่างโค้ด
using System;
public class Demo
{
public static void Main()
{
decimal val = 70.45M;
// ปัดเป็นจำนวนเต็ม (0 ทศนิยม) แบบ ToEven
decimal result = decimal.Round(val, 0, MidpointRounding.ToEven);
Console.WriteLine($"Original: {val}");
Console.WriteLine($"Rounded (ToEven): {result}"); // 70
// เปรียบเทียบ
Console.WriteLine($"Rounded (AwayFromZero): {decimal.Round(val, 0, MidpointRounding.AwayFromZero)}"); // 70
}
}
ผลลัพธ์
Original: 70.45
Rounded (ToEven): 70
Rounded (AwayFromZero): 70
ตัวอย่างที่เห็นความแตกต่างชัดเจน
decimal[] testValues = { 1.5M, 2.5M, 3.5M, 4.5M, -1.5M, -2.5M };
foreach (var v in testValues)
{
var toEven = decimal.Round(v, 0, MidpointRounding.ToEven);
var away = decimal.Round(v, 0, MidpointRounding.AwayFromZero);
Console.WriteLine($"{v,4} → ToEven: {toEven,2} | AwayFromZero: {away,2}");
}
ผลลัพธ์
1.5 → ToEven: 2 | AwayFromZero: 2
2.5 → ToEven: 2 | AwayFromZero: 3
3.5 → ToEven: 4 | AwayFromZero: 4
4.5 → ToEven: 4 | AwayFromZero: 5
-1.5 → ToEven: -2 | AwayFromZero: -2
-2.5 → ToEven: -2 | AwayFromZero: -3
เมื่อไหร่ควรใช้ ToEven
- Financial/Banking: ลด Bias สะสมในการคำนวณดอกเบี้ย ภาษี สถิติ
- Scientific Computing: มาตรฐาน IEEE 754
- Statistical Analysis: ป้องกัน Systematic Bias
เมื่อไหร่ควรใช้ AwayFromZero
- Business/Commercial: ลูกค้าคาดหวัง 2.5 → 3 (Traditional Rounding)
- Display/UI: User Expectation
- Legacy Systems: รองรับระบบเก่า
Default Behavior
decimal.Round(d)→ Default เป็น ToEvenMath.Round(double)→ Default เป็น ToEven (.NET Core 3.0+)Math.Round(double)→ Default เป็น AwayFromZero (.NET Framework - Legacy)
Best Practice: ระบุชัดเจนเสมอ
// ระบุ MidpointRounding ชัดเจน เพื่อไม่ให้สับสน
decimal.Round(value, 2, MidpointRounding.ToEven); // Banker's
decimal.Round(value, 2, MidpointRounding.AwayFromZero); // Traditional
// Extension Method สำหรับความชัดเจน
public static decimal RoundBankers(this decimal d, int decimals = 0)
=> decimal.Round(d, decimals, MidpointRounding.ToEven);
public static decimal RoundCommercial(this decimal d, int decimals = 0)
=> decimal.Round(d, decimals, MidpointRounding.AwayFromZero);