Lớp nào có thể được sử dụng để lưu trữ số tiền chính xác cho ứng dụng ngân hàng trong python?

Kiểu dữ liệu tốt nhất để sử dụng cho đơn vị tiền tệ trong C# là số thập phân. Kiểu thập phân là kiểu dữ liệu 128 bit phù hợp với tính toán tài chính tiền tệ. Loại thập phân có thể đại diện cho các giá trị nằm trong khoảng từ 1. 0 * 10^-28 đến xấp xỉ 7. 9 * 10^28 với 28-29 chữ số có nghĩa. Để khởi tạo một biến thập phân, hãy sử dụng hậu tố m hoặc M

số thập phân b = 2. 1m;

Ví dụ dưới đây cho thấy giá trị tối thiểu và tối đa của số thập phân

Thí dụ

Bản thử trực tiếp

using System;
namespace DemoApplication{
   public class Program{
      public static void Main(){
         Console.WriteLine($"Deciaml Min Value: {decimal.MinValue}");
         Console.WriteLine($"Deciaml Max Value: {decimal.MaxValue}");
         Console.ReadLine();
      }
   }
}

đầu ra

Deciaml Min Value: -79228162514264337593543950335 

Deciaml Max Value: 79228162514264337593543950335


Tập hợp hữu hạn các giá trị của kiểu thập phân có dạng (-1)^s * c * 10^-e, trong đó ký hiệu s là 0 hoặc 1, hệ số c được cho bởi 0 <= *c* < 2^ . Loại thập phân không hỗ trợ số 0 có dấu, số vô cùng hoặc NaN. Một số thập phân được biểu diễn dưới dạng số nguyên 96 bit được chia tỷ lệ theo lũy thừa mười. Đối với số thập phân có giá trị tuyệt đối nhỏ hơn 1. 0m, giá trị chính xác đến chữ số thập phân thứ 28, nhưng không xa hơn

Đối với số thập phân có giá trị tuyệt đối lớn hơn hoặc bằng 1. 0m, giá trị chính xác đến 28 hoặc 29 chữ số. Trái ngược với các kiểu dữ liệu float và double, các số phân số thập phân chẳng hạn như 0. 1 có thể được biểu diễn chính xác dưới dạng biểu diễn thập phân. Trong các biểu diễn float và double, các số như vậy thường là các phân số vô hạn, làm cho các biểu diễn đó dễ bị lỗi làm tròn hơn

Loại thập phân được ưa thích hơn float và double vì nó có độ chính xác cao hơn và phạm vi nhỏ hơn cả float và double

Bạn muốn tìm hiểu thêm về lý do tại sao bạn không bao giờ nên sử dụng float và double để tính toán tiền tệ?

qua

Đèn chùm Munish

·

Tháng 8. 21, 18 · Hướng dẫn

Giống

Bình luận

Tiết kiệm

tiếng riu ríu

196. 07K Lượt xem

Tham gia cộng đồng DZone và có được trải nghiệm thành viên đầy đủ

Tham gia miễn phí

Float và double không tốt cho thế giới tài chính (thậm chí cho mục đích quân sự), đừng bao giờ sử dụng chúng để tính toán tiền tệ. Nếu độ chính xác là một trong những yêu cầu của bạn, hãy sử dụng
Deciaml Min Value: -79228162514264337593543950335 

Deciaml Max Value: 79228162514264337593543950335

8 để thay thế

Hãy khám phá vấn đề này với sự trợ giúp của một ví dụ

Tất cả các giá trị dấu phẩy động có thể đại diện cho một lượng tiền tệ (bằng đô la và xu) không thể được lưu trữ chính xác như trong bộ nhớ. Vì vậy, nếu chúng ta muốn lưu trữ 0. 1 đô la (10 xu), float/double không thể lưu trữ như hiện tại. Thay vào đó, nhị phân chỉ có thể lưu trữ một giá trị gần đúng hơn (0. 100000001490116119384765625 ở dạng thập phân). Mức độ nghiêm trọng của vấn đề này trở nên nghiêm trọng (được gọi là mất ý nghĩa) khi chúng ta lặp đi lặp lại các phép tính số học (nhân hoặc chia) bằng cách sử dụng hai loại dữ liệu này. Dưới đây, chúng tôi sẽ chứng minh điều này có thể trông như thế nào

Dưới đây là một ví dụ về việc mất độ chính xác khi sử dụng gấp đôi

public class DoubleForCurrency {
    public static void main(String[] args) {
        double total = 0.2;
        for (int i = 0; i < 100; i++) {
            total += 0.2;
        }
        System.out.println("total = " + total);
    }
}                                                    


đầu ra chương trình

total = 20.19999999999996


Đầu ra lẽ ra phải là

Deciaml Min Value: -79228162514264337593543950335 

Deciaml Max Value: 79228162514264337593543950335

9 (20 đô la và 20 xu), nhưng phép tính dấu phẩy động đã khiến nó trở thành
public class DoubleForCurrency {
    public static void main(String[] args) {
        double total = 0.2;
        for (int i = 0; i < 100; i++) {
            total += 0.2;
        }
        System.out.println("total = " + total);
    }
}                                                    
0. Đây là sự mất độ chính xác (hoặc mất ý nghĩa)

Nguyên nhân mất ý nghĩa

Số học dấu phẩy động

Trong điện toán, số học dấu phẩy động (FP) là một số học sử dụng biểu diễn công thức của các số thực dưới dạng gần đúng để hỗ trợ cân bằng giữa phạm vi và độ chính xác

Theo Wikipedia

“Một số hữu tỉ có khai triển tận cùng hay không là phụ thuộc vào cơ số. Ví dụ: trong cơ số 10, số 1/2 có khai triển kết thúc (0. 5) trong khi số 1/3 thì không (0. 333…). Trong cơ số 2, chỉ những số hữu tỷ có mẫu số là lũy thừa của 2 (chẳng hạn như 1/2 hoặc 3/16) mới bị kết thúc. Bất kỳ số hữu tỷ nào có mẫu số có thừa số nguyên tố khác 2 sẽ có khai triển nhị phân vô hạn. Điều này có nghĩa là các số có vẻ ngắn và chính xác khi được viết ở định dạng thập phân có thể cần phải được tính gần đúng khi được chuyển đổi thành dấu phẩy động nhị phân. Ví dụ, số thập phân 0. 1 không thể biểu diễn ở dạng dấu phẩy động nhị phân với bất kỳ độ chính xác hữu hạn nào;

e = −4;

Khi làm tròn thành 24 bit, điều này trở thành

e = −4; . 100000001490116119384765625 ở dạng thập phân. "

BigDecimal để giải cứu

BigDecimal đại diện cho số thập phân có chữ ký của độ chính xác tùy ý với tỷ lệ liên quan. BigDecimal cung cấp toàn quyền kiểm soát độ chính xác và làm tròn giá trị số. Trên thực tế, có thể tính giá trị của số pi đến 2 tỷ chữ số thập phân bằng BigDecimal, với bộ nhớ vật lý khả dụng là giới hạn duy nhất

Đó là lý do tại sao chúng ta luôn ưu tiên BigDecimal hoặc BigInteger để tính toán tài chính

Ghi chú đặc biệt

loại nguyên thủy. int và long cũng hữu ích cho việc tính toán tiền tệ nếu không yêu cầu độ chính xác thập phân

Chúng ta thực sự nên tránh sử dụng hàm tạo BigDecimal (giá trị kép) và thay vào đó, chúng ta nên thực sự thích sử dụng BigDecimal(String), vì BigDecimal (0. 1) dẫn đến (0. 10000000000000000055511151231257827021181583404541015625) đang được lưu trữ trong phiên bản BigDecimal. Ngược lại, BigDecimal ("0. 1") lưu chính xác 0. 1

Độ chính xác và Quy mô là gì?

Độ chính xác là tổng số chữ số (hoặc chữ số có nghĩa) của một số thực

Tỷ lệ chỉ định số chữ số sau vị trí thập phân. Ví dụ, 12. 345 có độ chính xác là 5 (tổng các chữ số) và tỷ lệ là 3 (số chữ số bên phải phần thập phân)

Làm cách nào chúng ta có thể định dạng giá trị BigDecimal mà không lấy lũy thừa trong kết quả và loại bỏ các số 0 ở cuối?

Chúng tôi có thể nhận được lũy thừa trong kết quả tính toán nếu chúng tôi không tuân theo một số phương pháp hay nhất khi sử dụng

Deciaml Min Value: -79228162514264337593543950335 

Deciaml Max Value: 79228162514264337593543950335

8. Dưới đây là đoạn mã hiển thị một ví dụ sử dụng hữu ích để xử lý kết quả tính toán với
Deciaml Min Value: -79228162514264337593543950335 

Deciaml Max Value: 79228162514264337593543950335

8

Làm tròn số thập phân lớn

import java.math.BigDecimal;

public class BigDecimalForCurrency {

    public static void main(String[] args) {
        int scale = 4;
        double value = 0.11111;
        BigDecimal tempBig = new BigDecimal(Double.toString(value));
        tempBig = tempBig.setScale(scale, BigDecimal.ROUND_HALF_EVEN);
        String strValue = tempBig.stripTrailingZeros().toPlainString();
        System.out.println("tempBig = " + strValue);
    }
}                                                            

Đầu ra chương trình

tempBig = 0.1111

Làm cách nào để bạn in một giá trị tiền tệ nhất định cho Ngôn ngữ Ấn Độ (Đơn vị tiền tệ INR)?

Lớp

total = 20.19999999999996
1 được thiết kế đặc biệt cho mục đích này. Ký hiệu tiền tệ & Chế độ làm tròn được đặt tự động dựa trên ngôn ngữ sử dụng
total = 20.19999999999996
1. Hãy xem điều này trong hành động

Ví dụ NumberFormat

________số 8


đầu ra chương trình

tempBig = Rs.22.12146


Chỉ vậy thôi, mọi việc đều do

total = 20.19999999999996
1 lo liệu

Các biện pháp phòng ngừa

  • Hàm tạo BigDecimal(String) phải luôn được ưu tiên hơn BigDecimal(Double) vì việc sử dụng
    total = 20.19999999999996
    4 không thể đoán trước do double không thể biểu thị 0. 1 chính xác như 0. 1
  • Nếu double phải được sử dụng để khởi tạo BigDecimal, hãy sử dụng
    total = 20.19999999999996
    5, chuyển đổi giá trị Double thành Chuỗi bằng phương thức
    total = 20.19999999999996
    6(double)
  • Chế độ làm tròn nên được cung cấp trong khi đặt tỷ lệ
  • total = 20.19999999999996
    7 cắt bỏ tất cả các số 0 ở cuối
  • total = 20.19999999999996
    8 có thể sử dụng ký hiệu khoa học nhưng,
    total = 20.19999999999996
    9 sẽ không bao giờ trả về kết quả lũy thừa

Bạn có biết không?

Sử dụng Float, Double thay vì BigDecimal có thể gây tử vong cho quân đội

Vào ngày 25 tháng 2 năm 1991, một sự mất mát đáng kể trong khẩu đội tên lửa MIM-104 Patriot đã khiến nó không thể đánh chặn một tên lửa Scud đang bay tới ở Dhahran, Ả Rập Xê Út, góp phần gây ra cái chết của 28 binh sĩ Hoa Kỳ. S. Biệt đội trưởng khu phố 14 của quân đội

Chế độ làm tròn của Banker

Kể từ khi giới thiệu IEEE 754, phương pháp mặc định (làm tròn đến số thập phân gần nhất, liên kết với số chẵn và đôi khi được gọi là Làm tròn của Banker hoặc

import java.math.BigDecimal;

public class BigDecimalForCurrency {

    public static void main(String[] args) {
        int scale = 4;
        double value = 0.11111;
        BigDecimal tempBig = new BigDecimal(Double.toString(value));
        tempBig = tempBig.setScale(scale, BigDecimal.ROUND_HALF_EVEN);
        String strValue = tempBig.stripTrailingZeros().toPlainString();
        System.out.println("tempBig = " + strValue);
    }
}                                                            
0) được sử dụng phổ biến hơn ở Hoa Kỳ. Phương pháp này làm tròn kết quả lý tưởng (chính xác vô cùng) của một phép toán số học thành giá trị biểu diễn gần nhất và đưa ra kết quả biểu diễn đó. Trong trường hợp hòa, giá trị sẽ làm cho ý nghĩa và kết thúc bằng một chữ số chẵn được chọn

Loại dữ liệu nào được sử dụng để lưu trữ giá trị tiền tệ?

Kiểu dữ liệu MONEY lưu trữ số lượng tiền tệ. Giống như kiểu dữ liệu DECIMAL(p,s), MONEY có thể lưu trữ số điểm cố định lên đến tối đa 32 chữ số có nghĩa, trong đó p là tổng số chữ số có nghĩa (độ chính xác) và s là số chữ số ở bên phải

Loại dữ liệu nào được sử dụng cho tiền tệ trong Python?

Kiểu float của Python là bước đầu tiên tự nhiên để biểu thị số tiền trong mã. Hầu như tất cả các nền tảng ánh xạ Python đều có độ chính xác kép của IEEE-754.

Bạn có nên sử dụng tiền thả nổi?

Khi thực hiện bất kỳ loại phép tính nào với tiền tệ, độ chính xác là vô cùng quan trọng. Và các số có dấu phẩy động (số float và double) không có biểu diễn đủ chính xác để ngăn các lỗi làm tròn tích lũy khi thực hiện phép tính số học với các giá trị tiền tệ .

Làm thế nào để lưu trữ tiền trong cơ sở dữ liệu?

Sử dụng kiểu dữ liệu DECIMAL hoặc NUMERIC để lưu trữ giá trị tiền tệ trong hệ thống cơ sở dữ liệu quan hệ. Loại này lưu trữ các giá trị thập phân và sẽ không có lỗi làm tròn khi tính tiền như U. S. USD. Khai báo NUMERIC(p, s) có độ chính xác p và và tỷ lệ s