Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

C# MidpointRounding.ToEven - ปัดเศษแบบ Banker's Rounding

MidpointRounding.ToEven ใช้กับ decimal.Round() และ Math.Round() เพื่อปัดเศษแบบ Banker's Rounding (Round Half to Even) - มาตรฐาน IEEE 754

Banker's Rounding คืออะไร

เมื่อค่าอยู่ตรงกลาง (x.5) จะปัดไปยังเลขคู่ที่ใกล้ที่สุด:

ค่าAwayFromZeroToEven (Banker's)
1.522
2.532
3.544
4.554
-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 เป็น ToEven
  • Math.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);