2009-03-28 22 views
325

Loại dữ liệu tốt nhất để sử dụng cho tiền trong C# là gì?Loại dữ liệu tốt nhất để sử dụng cho tiền trong C# là gì?

+4

Bạn có thể tìm thấy câu trả lời từ [post] này (http://stackoverflow.com/questions/618056/what-is-the-best-way-to-store-a-money-value-in-the-database) Hữu ích. – ntombela

+0

Đây là bản đồ cho tất cả các loại dữ liệu: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-data-type-mappings – JohnLBevan

+0

Ngoài ra, nếu sử dụng chú thích dữ liệu, hãy bao gồm ' sử dụng System.ComponentModel.DataAnnotations; '...' [DataType (DataType.Currency)] 'https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatype(v=vs.110) .aspx – JohnLBevan

Trả lời

323

Vì nó được mô tả tại decimal như:

Từ khóa thập phân chỉ ra một kiểu dữ liệu 128-bit. So với loại dấu phẩy động, loại thập phân có độ chính xác cao hơn và một dải nhỏ hơn , làm cho nó thích hợp cho tài chính và tiền tệ tính toán.

Bạn có thể sử dụng một số thập phân như sau:

decimal myMoney = 300.5m; 
+34

Bạn nên giải thích điều gì về liên kết đó là quan trọng. Một câu trả lời phải đủ tốt theo cách riêng của mình, với một liên kết làm tham chiếu hoặc chi tiết bổ sung. Xem http://stackoverflow.com/help/how-to-answer – EnvisionAndDevelop

+2

Vì vậy, câu trả lời có độ dài tối thiểu có thể ít ký tự hơn bình luận dài tối thiểu - thú vị! Không phải là tôi có một vấn đề với câu trả lời ngắn gọn/súc tích, đặc biệt là khi nó cũng "sâu" trong đó nó liên kết để thảo luận thêm. –

+3

Câu trả lời tuyệt vời và tôi không cảm thấy cần giải thích thêm vì nó hoàn toàn trả lời câu hỏi. Các liên kết đến tài liệu MSDN là một tiền thưởng như xa như tôi đang quan tâm. Bravo! – trnelson

106

System.Decimal

Các kiểu giá trị thập phân đại diện cho số thập phân khác nhau, từ tích cực 79.228.162.514.264.337.593.543.950.335 để tiêu cực 79.228.162.514.264.337.593.543.950.335. Loại giá trị thập phân phù hợp cho các tính toán tài chính đòi hỏi số lượng lớn các chữ số nguyên và số nguyên có nghĩa và không có lỗi vòng tròn. Loại thập phân không loại bỏ nhu cầu làm tròn. Thay vào đó, nó giảm thiểu lỗi do làm tròn.

Tôi muốn trỏ đến this excellent answer bởi zneak về lý do tại sao không nên sử dụng gấp đôi.

20

Decimal. Nếu bạn chọn gấp đôi, bạn sẽ tự mình mở để làm tròn lỗi số

+0

Làm thế nào để bạn không có số thập phân? –

+6

@Jess 'double' có thể giới thiệu lỗi làm tròn vì dấu phẩy động không thể đại diện cho tất cả các số chính xác (ví dụ: 0,01 không có đại diện chính xác trong dấu phẩy động). 'Thập phân', mặt khác, * có * đại diện cho số * chính xác *. (Giao dịch là 'Thập phân 'có phạm vi nhỏ hơn điểm động) Điểm nổi có thể cho bạn * lỗi làm tròn * vô tình (ví dụ: 0,01 + 0,01! = 0,02'). 'Decimal' có thể cung cấp cho bạn các lỗi làm tròn, nhưng chỉ khi bạn yêu cầu nó (ví dụ' Math.Round (0,01 0,02) 'trả về số không) –

+2

@IanBoyd: Giá trị" $ 1,57 "có thể được biểu diễn chính xác (gấp đôi) 157. Nếu một người sử dụng 'double' và cẩn thận áp dụng làm tròn và làm tròn tên miền cụ thể khi thích hợp, nó có thể hoàn toàn chính xác. Nếu một trong số đó là sloppy trong làm tròn của một người, 'thập phân 'có thể mang lại kết quả không đúng ngữ nghĩa (ví dụ:nếu có thêm nhiều giá trị được cho là được làm tròn thành đồng xu gần nhất, nhưng không thực sự xung quanh chúng trước tiên). Điều tốt duy nhất về 'thập phân' là việc chia tỷ lệ được tích hợp sẵn. – supercat

15

số thập phân có phạm vi nhỏ hơn, nhưng chính xác hơn - vì vậy bạn không mất tất cả các đồng xu theo thời gian!

Chi tiết đầy đủ ở đây:

http://msdn.microsoft.com/en-us/library/364x0z75.aspx

+5

Ai muốn giữ tiền xu của họ? :) – JeremyK

+0

Ai đó nên bỏ qua các phân số của một xu và gửi chúng vào một tài khoản ngân hàng. Điều đó chưa bao giờ được thực hiện trước đó phải không? – hardba11

+0

@ hardba11 Nó đã được, và ông đã giàu có như triệu phú, nhưng sau đó bị bắt giữ. Bởi vì thực sự những phân số đó là cho ngân hàng, nó là một phần của tiền thưởng ngân hàng có – Thaina

61

Sử dụng Money pattern từ Patterns of Enterprise Application Architecture; chỉ định số tiền dưới dạng thập phân và đơn vị tiền tệ dưới dạng enum.

+1

Tôi đã thực sự đề xuất điều này, nhưng tôi kiếm tiền một lớp để tôi có thể xác định tỷ giá hối đoái (liên quan đến "tiền tệ cơ sở", thường là đô la Mỹ [mà tôi đặt để có tỷ giá hối đoái là 1.00]). –

+15

http://www.codeproject.com/KB/recipes/MoneyTypeForCLR.aspx –

+5

Đối với khách truy cập trong tương lai của chủ đề này (như tôi), hiện tại có: https://www.nuget.org/packages/Money/ và nó đá! – Korijn

4

Tạo lớp học của riêng bạn. Điều này có vẻ kỳ lạ, nhưng một loại .Net là không đủ để trang trải các loại tiền tệ khác nhau.

13

Đồng ý với mẫu Tiền: Xử lý đơn vị tiền tệ quá cồng kềnh khi bạn sử dụng số thập phân.

Nếu bạn tạo một loại tiền tệ, bạn có thể đặt tất cả logic liên quan đến tiền đó, bao gồm phương thức ToString() đúng, kiểm soát nhiều hơn các giá trị phân tích và kiểm soát tốt hơn các bộ phận.

Ngoài ra, với một loại tiền tệ, không có cơ hội vô tình trộn tiền với các dữ liệu khác.

7

Tùy chọn khác (đặc biệt nếu bạn đang lăn bạn sở hữu lớp) là sử dụng int hoặc int64 và chỉ định bốn chữ số thấp hơn (hoặc thậm chí có thể là 2) làm "bên phải dấu thập phân". Vì vậy, "trên các cạnh" bạn sẽ cần một số "* 10000" trên đường vào và một số "/ 10000" trên đường ra. Đây là cơ chế lưu trữ được sử dụng bởi Máy chủ SQL của Microsoft, xem http://msdn.microsoft.com/en-au/library/ms179882.aspx

Điều quan trọng là tất cả tổng kết của bạn có thể được thực hiện bằng cách sử dụng số học số nguyên (nhanh).

1

Hầu hết các ứng dụng tôi đã làm việc với việc sử dụng decimal để đại diện cho tiền. Điều này được dựa trên giả định rằng ứng dụng sẽ không bao giờ được quan tâm với nhiều hơn một loại tiền tệ.

Giả thiết này có thể dựa trên một giả định khác, rằng ứng dụng sẽ không bao giờ được sử dụng ở các quốc gia khác với các loại tiền tệ khác nhau. Tôi đã nhìn thấy những trường hợp đã chứng minh là sai.

Bây giờ giả định đó đang được thử thách theo một cách mới: Các loại tiền tệ mới như Bitcoin đang trở nên phổ biến hơn và chúng không cụ thể cho bất kỳ quốc gia nào. Nó không phải là không thực tế rằng một ứng dụng được sử dụng trong chỉ một quốc gia vẫn có thể cần phải hỗ trợ nhiều loại tiền tệ.

Một số người sẽ nói rằng việc tạo hoặc thậm chí sử dụng loại tiền chỉ là "mạ vàng" hoặc thêm độ phức tạp vượt quá các yêu cầu đã biết. Tôi rất không đồng ý. Khái niệm phổ biến hơn nằm trong miền của bạn, điều quan trọng hơn là thực hiện một nỗ lực hợp lý để sử dụng sự trừu tượng chính xác ở phía trước. Nếu bạn muốn thấy sự phức tạp, hãy thử làm việc trong một ứng dụng sử dụng để sử dụng decimal và bây giờ có thêm một thuộc tính Currency bên cạnh mỗi thuộc tính decimal.

Nếu bạn sử dụng sai trừu tượng lên phía trước, thay thế nó sau này sẽ là một trăm lần làm việc nhiều hơn nữa. Điều đó có nghĩa là có khả năng đưa các khuyết tật vào mã hiện có, và phần tốt nhất là những khiếm khuyết đó có thể sẽ liên quan đến số tiền, giao dịch bằng tiền, hoặc bất cứ thứ gì có tiền.

Và không khó sử dụng thứ gì khác ngoài số thập phân. Google "nuget loại tiền" và bạn sẽ thấy rằng nhiều nhà phát triển đã tạo ra những trừu tượng như vậy (bao gồm cả tôi.) Thật dễ dàng. Việc này dễ dàng như sử dụng DateTime thay vì lưu trữ ngày trong một số string.

Các vấn đề liên quan