ฉันเข้าใจว่า BigDecimal แนะนำแนวทางปฏิบัติที่ดีที่สุดในการแสดงมูลค่าเงินใน Java คุณใช้อะไร? มีห้องสมุดที่ดีกว่าที่คุณต้องการใช้แทนหรือไม่?
ฉันเข้าใจว่า BigDecimal แนะนำแนวทางปฏิบัติที่ดีที่สุดในการแสดงมูลค่าเงินใน Java คุณใช้อะไร? มีห้องสมุดที่ดีกว่าที่คุณต้องการใช้แทนหรือไม่?
คำตอบ:
BigDecimal
ทุกทาง. ฉันเคยได้ยินว่ามีคนบางคนสร้างของตัวเองCash
หรือMoney
ชั้นเรียนที่ห่อหุ้มมูลค่าเงินสดด้วยสกุลเงิน แต่ภายใต้ผิวหนังมันก็ยังคงBigDecimal
มีBigDecimal.ROUND_HALF_EVEN
การปัดเศษ
แก้ไข: ดังที่ Don กล่าวถึงในคำตอบของเขามีโครงการโอเพ่นซอร์สเช่นเวลาและเงินและในขณะที่ฉันปรบมือให้พวกเขาที่พยายามป้องกันไม่ให้นักพัฒนาต้องสร้างวงล้อใหม่ฉันแค่ไม่มีความมั่นใจเพียงพอในไลบรารีก่อนอัลฟ่าที่จะใช้ ในสภาพแวดล้อมการผลิต นอกจากนี้หากคุณขุดไปรอบ ๆ ใต้ฝากระโปรงคุณจะเห็นว่าพวกเขาใช้BigDecimal
เช่นกัน
ฉันไม่ได้แสดงความคิดเห็นที่นี่ แต่มีข้อโต้แย้งที่ค่อนข้างดีกับ BigDecimal ที่ใครบางคนควรโยนทิ้ง:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
ห้องสมุดที่สะดวกสบายที่ฉันพบก่อนหน้านี้คือห้องสมุดJoda-Money หนึ่งในการใช้งานนั้นขึ้นอยู่กับ BigDecimal เป็นไปตามข้อกำหนดISO-4217สำหรับสกุลเงินและสามารถรองรับรายการสกุลเงินที่กำหนดเองได้ (โหลดผ่าน CVS)
ไลบรารีนี้มีไฟล์จำนวนน้อยที่สามารถเข้าถึงได้อย่างรวดเร็วหากจำเป็นต้องมีการปรับเปลี่ยน Joda-Money เผยแพร่ภายใต้ลิขสิทธิ์ Apache 2.0
ถ้าคุณใช้แค่ดอลลาร์กับเซนต์ฉันจะใช้ long (ชดเชยด้วยทศนิยม 2 ตำแหน่ง) หากคุณต้องการรายละเอียดเพิ่มเติมทศนิยมใหญ่อาจเป็นวิธีที่จะไป
ไม่ว่าจะด้วยวิธีใดฉันอาจจะขยายคลาสให้มี. toString () ที่ใช้รูปแบบที่ถูกต้องและเป็นที่สำหรับใส่วิธีการอื่น ๆ ที่อาจเกิดขึ้น (เป็นเวลานานการคูณและการหารจะผิดปกติถ้าทศนิยมไม่ได้ ไม่ปรับ)
นอกจากนี้หากคุณใช้กำหนดคลาสและอินเทอร์เฟซของคุณเองคุณสามารถแทนที่การใช้งานได้ตามต้องการ
BigDecimal
หรือการแสดงจุดคงที่อีกแบบหนึ่งคือสิ่งที่จำเป็นโดยทั่วไปสำหรับเงิน
การแทนค่าและการคำนวณจุดลอยตัว ( Double
, Float
) ไม่ตรงทำให้ผลลัพธ์ที่ผิดพลาด
คุณต้องระมัดระวังในการจัดการกับเวลาและเงิน
เมื่อคุณทำงานกับเงินฉันหวังว่าทุกคนควรรู้ว่าไม่ควรใช้โฟลตหรือสองเท่า
แต่ฉันไม่แน่ใจเกี่ยวกับ BigDecimal
ในกรณีส่วนใหญ่คุณจะสบายดีถ้าคุณติดตามเซ็นต์แบบ int หรือ long ด้วยวิธีนี้คุณจะไม่จัดการกับตำแหน่งทศนิยม
คุณจะแสดงเฉพาะดอลลาร์เมื่อคุณพิมพ์ ทำงานกับเซ็นต์ภายในโดยใช้จำนวนเต็มเสมอ อาจเป็นเรื่องยุ่งยากหากจำเป็นต้องหารหรือจำเป็นต้องใช้ Math.abs ()
อย่างไรก็ตามคุณอาจสนใจครึ่งเซ็นต์หรือแม้แต่หนึ่งในร้อยก็ได้ ฉันไม่รู้วิธีที่ดีในการทำเช่นนี้ คุณอาจต้องจัดการกับหนึ่งในพันของเซนต์และใช้แบบยาว หรือบางทีคุณอาจถูกบังคับให้ใช้ BigDecimal
ฉันจะอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ แต่อย่าสนใจทุกคนที่เริ่มพูดถึงการใช้ float หรือ double เพื่อแทนเงิน พวกเขาแค่ถามปัญหา
ฉันรู้สึกว่าคำแนะนำของฉันยังไม่สมบูรณ์ดังนั้นโปรดใส่ให้มากขึ้น คุณกำลังเผชิญกับประเภทอันตราย!
การสร้างคลาส Money คือหนทางที่จะไป ใช้ BigDecimal (หรือแม้แต่ int) ที่อยู่ข้างใต้ จากนั้นใช้คลาสสกุลเงินเพื่อกำหนดรูปแบบการปัดเศษ
น่าเสียดายที่ไม่มีตัวดำเนินการที่ใช้ Java มากเกินไปทำให้การสร้างประเภทพื้นฐานดังกล่าวค่อนข้างไม่สะดวก
ไม่ใช่ BigDecimal แน่นอน มีกฎพิเศษมากมายสำหรับการปัดเศษและการนำเสนอที่คุณต้องกังวล
Martin Fowler แนะนำให้ใช้คลาสMoneyโดยเฉพาะเพื่อแสดงจำนวนสกุลเงินและยังใช้กฎสำหรับการแปลงสกุลเงินอีกด้วย
เฮ้นี่เป็นบทความที่น่าสนใจมากเกี่ยวกับ BigDecimal และเป็นตัวอย่างที่อธิบายว่าทำไมบางครั้งจึงใช้แทนคู่ผสม BigDecimal กวดวิชา
คุณสามารถใช้คลาส DecimalFormat เมื่อแสดงค่าสกุลเงินในท้ายที่สุด ให้การสนับสนุนการแปลเป็นภาษาท้องถิ่นและค่อนข้างขยายได้
ฉันจะห่อหุ้ม BigDecimal ในชั้น Money ซึ่งมีสกุลเงินเหมือนที่ใครบางคนกล่าวถึง สิ่งสำคัญคือคุณทำการทดสอบหน่วยจำนวนมากและโดยเฉพาะอย่างยิ่งหากทำงานกับสกุลเงินที่แตกต่างกัน นอกจากนี้ยังเป็นความคิดที่ดีหากคุณเพิ่มคอนสตรัคเตอร์ที่สะดวกซึ่งใช้สตริงหรือวิธีการจากโรงงานที่ทำเช่นเดียวกันเพื่อให้คุณสามารถเขียนการทดสอบของคุณได้ดังนี้:
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
มีข้อ จำกัด และข้อมูลเฉพาะที่เกี่ยวข้องเสมอ ใครก็ตามที่ไม่มีประสบการณ์เพียงพอที่จะเข้าใจประเด็นที่ละเอียดอ่อนที่ระบุไว้ในบทความต่อไปนี้ควรพิจารณาใหม่อย่างจริงจังก่อนจัดการกับข้อมูลทางการเงินในโลกแห่งความเป็นจริง:
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal แทบจะไม่ได้เป็นเพียงการนำเสนอที่ถูกต้องหรือเป็นเพียงส่วนเดียวของปริศนา ด้วยเงื่อนไขบางประการการใช้คลาส Money ที่ได้รับการสนับสนุนโดยเซ็นต์ที่จัดเก็บเป็นจำนวนเต็มอาจเพียงพอและจะเร็วกว่า BigDecimal มาก ใช่นั่นหมายถึงการใช้ดอลลาร์เป็นสกุลเงินและ จำกัด จำนวนเงิน แต่ข้อ จำกัด ดังกล่าวเป็นที่ยอมรับอย่างสมบูรณ์สำหรับกรณีการใช้งานจำนวนมากและทุกสกุลเงินก็มีกรณีพิเศษสำหรับการปัดเศษและนิกายย่อยอยู่แล้วดังนั้นจึงไม่มีโซลูชัน "สากล"