หัวข้อ 70/91· การพัฒนาซอฟต์แวร์และการให้บริการดิจิทัล

การจัดสรรต้นทุนแบบเป๊ะถึงเซ็นต์

การแบ่งยอดเงินรวม — เงินอุดหนุนร่วม ใบแจ้งหนี้โครงสร้างพื้นฐาน ตัวเลขผลกระทบต่องบประมาณ — ให้ผู้รับหลายรายด้วยเลขคณิตเปอร์เซ็นต์แบบไร้เดียงสา มักได้ส่วนแบ่งที่รวมกลับไม่ตรงกับยอดเดิม การจัดสรรแบบเป๊ะถึงเซ็นต์คือวิธีแก้: วิธีแบบจำนวนเต็ม/ทศนิยมที่ทำงานในหน่วยย่อยที่สุดของสกุลเงิน (เซ็นต์) และรับประกันว่าส่วนแบ่งรวมกันได้ พอดี เท่ากับยอดทั้งหมด ไม่ว่าจะหารไม่ลงตัวเพียงใด วิศวกรซอฟต์แวร์ทุกคนที่ต้องทำให้ยอดที่แบ่งแล้วลงตัวถึงเซ็นต์ — เงินเดือน การจ่ายเงินอุดหนุน การเรียกเก็บค่าบริการร่วม — ต้องการรูปแบบนี้ ไม่ใช่เปอร์เซ็นต์ทศนิยมลอยตัว

ทำไมจึงสำคัญ

นี่คือรูปแบบพื้นฐานที่มีชื่อเรียกในวิศวกรรมซอฟต์แวร์องค์กร: Patterns of Enterprise Application Architecture ของ Martin Fowler (2002) บันทึก Money และ Allocate ไว้ก็เพราะ "แบ่ง $100 เป็นสามส่วน" เป็นปัญหาที่โค้ดไร้เดียงสาทำผิดอยู่เสมอ และผิดอย่างเงียบๆ — ข้อผิดพลาดปรากฏเมื่อมีคนกระทบยอดบัญชีและพบว่าส่วนแบ่งขาด (หรือเกิน) ยอดรวมไปหนึ่งเซ็นต์ ในงานเศรษฐศาสตร์สุขภาพและการเงินของ NHS นี่ไม่ใช่เรื่องเชิงวิชาการ: ยอดผลกระทบต่องบประมาณถูกแบ่งตามสถานที่ ปี หรือสำนัก ค่าโครงสร้างพื้นฐานและใบอนุญาตร่วมถูกกระจายให้แผนกตามจำนวนพนักงานหรือสัดส่วนกิจกรรม ทุกการแบ่งเหล่านี้ต้องลงตัวพอดี เพราะผู้อำนวยการฝ่ายการเงินที่ได้รับส่วนแบ่งที่รวมกันไม่เท่ายอดรวมจะเลิกไว้ใจทั้งแบบจำลอง

คณิตศาสตร์

วิธีไร้เดียงสา (ผิดพลาด):
  ส่วน_i = ปัด(ยอดรวม × สัดส่วน_i / Σ สัดส่วน)     — ปัดแต่ละส่วนแยกกัน

วิธีแม่นยำ (เศษมากที่สุด / "largest remainder allocation"):
  1. ฐาน_i = ปัดลง(ยอดรวม_หน่วยย่อยที่สุด × สัดส่วน_i / Σ สัดส่วน)   — เฉพาะหน่วยย่อยที่สุดแบบเต็ม (เซ็นต์)
  2. เศษ = ยอดรวม_หน่วยย่อยที่สุด − Σ ฐาน_i                          — เซ็นต์ที่เหลือ เสมอ < จำนวนผู้รับ
  3. แจกหน่วยย่อยที่สุดเพิ่ม 1 หน่วยให้ผู้รับ `เศษ` รายที่มีเศษส่วนมากที่สุด
     จากขั้นที่ 1 จนกว่าเศษจะหมด

ผลลัพธ์: Σ ส่วน_i == ยอดรวม เสมอ โดยโครงสร้าง

วิธีที่แม่นยำไม่เคยปัดส่วนใดส่วนหนึ่งแยกกัน — มันปัด การจัดสรรทั้งหมด เป็นปฏิบัติการเดียว และนั่นคือสิ่งที่ทำให้คงตัวไม่แปรผันของผลรวมเป็นจริง

ตัวอย่างที่คำนวณแล้ว

แบ่ง $100.00 เป็นสามส่วนเท่ากัน (สัดส่วน = [1, 1, 1])

วิธีไร้เดียงสา: $100.00 ÷ 3 = $33.333… ปัดแยกกันเป็นเซ็นต์ที่ใกล้ที่สุดได้ $33.33 ต่อผู้รับ รวมแล้ว: $33.33 × 3 = $99.99 — เซ็นต์หายไปหนึ่ง และไม่มีรายการเดี่ยวใด "ผิด" มากพอที่จะสังเกตเห็นด้วยการตรวจดู

วิธีแม่นยำ: ฐาน = $33.33 สำหรับทั้งสามราย (รวม 9,999 หน่วยย่อยที่สุดจาก ปัดลง(10,000 / 3) = 3,333 เซ็นต์ต่อราย) เหลือเศษ 1 เซ็นต์ (10,000 − 9,999) เซ็นต์ที่เหลือเพียงหนึ่งนั้นไปที่ผู้รับที่มีเศษส่วนมากที่สุดในการหาร — ผู้รับรายใดโดยเฉพาะเป็นรายละเอียดภายในของการตัดสินกรณีเสมอ ไม่ใช่สิ่งที่ผู้เรียกควรพึ่งพา ผู้รับสองรายได้ $33.33 และหนึ่งรายได้ $33.34 และสามส่วนรวมกันได้ $100.00 พอดี

นี่คือเลขคณิตที่การวิเคราะห์ผลกระทบต่องบประมาณต้องการทุกครั้งที่ตัวเลขผลกระทบต่องบประมาณรวมต้องถูกแบ่งตามสถานที่ กลุ่มประชากร หรือปีงบประมาณ และกระทบยอดกลับกับยอดรวมที่เผยแพร่ — ดูการรวมต้นทุนที่ปลอดภัยต่อสกุลเงินสำหรับปัญหาคู่กันคือการรวมรายการจำนวนมากเช่นนั้นโดยไม่คลาดเคลื่อน

ความเชื่อมโยงกับวิศวกรรมซอฟต์แวร์

นี่คือ "รูปแบบ Money" จากสถาปัตยกรรมซอฟต์แวร์องค์กรอย่างแท้จริง — รูปแบบพื้นฐานที่มีชื่อเรียกสำหรับบั๊กประเภทนี้โดยเฉพาะ ไม่ใช่กลเม็ดครั้งเดียว ความล้มเหลวในการกระทบยอดทางการเงินจริงเคยถูกส่งขึ้นระบบจริงจากบั๊กประเภทนี้เอง: การแบ่งสัดส่วนที่คำนวณใน f64 ปัดต่อผู้รับ และไม่เคยตรวจสอบกับยอดรวมเดิม เชื่อมโยงโดยตรงกับโมดูลต้นทุนรวมของการเป็นเจ้าของของคลังนี้ ซึ่งปัจจุบันรวมต้นทุนทศนิยมลอยตัวธรรมดาข้ามปีและตัวเลือก — วินัยความแม่นยำเดียวกันใช้เมื่อยอด TCO หรือผลกระทบต่องบประมาณต้องถูกจัดสรร ไม่ใช่แค่รวม

ข้อผิดพลาดที่พบบ่อย

  • เปอร์เซ็นต์แล้วปัดแทนเศษมากที่สุด: จัดสรรด้วยเปอร์เซ็นต์ทศนิยมลอยตัวและปัดผู้รับแต่ละรายแยกกัน ซึ่งทบทวีความคลาดเคลื่อนจากการปัดและแทบไม่รวมกลับเท่ายอดรวม โดยเฉพาะเมื่อมีผู้รับหลายราย
  • ละเลยเลขชี้กำลังหน่วยย่อยที่สุดของสกุลเงิน: สมมุติว่าทุกสกุลเงินมี 2 ตำแหน่งทศนิยม — เยนญี่ปุ่นมี 0 บางสกุลเงินมี 3 — การแบ่งสัดส่วนที่เขียนเองมักฝัง 2 ไว้ตายตัวและพังอย่างเงียบๆ กับสกุลเงินอื่น ส่วนรูทีนการจัดสรรที่แม่นยำอ่านเลขชี้กำลังจากสกุลเงินเอง (ISO 4217)
  • จัดสรรเศษที่จัดสรรไปแล้วซ้ำ: รันรูทีนการจัดสรรอีกครั้งกับสิ่งที่เหลือจากการจัดสรรก่อนหน้า โดยไม่มีการตรวจสอบความเป็นไอเดมโพเทนต์ ซึ่งอาจให้เครดิตเซ็นต์เดียวกันสองครั้งแก่ผู้รับรายเดียวกัน

แหล่งที่มา

  • Fowler M. "Patterns of Enterprise Application Architecture." Addison-Wesley, 2002 — รูปแบบ Money และ Allocate.
  • ISO 4217 — มาตรฐานรหัสสกุลเงินและกองทุน ซึ่งกำหนดเลขชี้กำลังหน่วยย่อยที่สุดของแต่ละสกุลเงิน