Rất nhiều người sẽ đề xuất sử dụng BigDecimal và nếu bạn không biết làm thế nào để sử dụng làm tròn trong dự án của bạn, đó là những gì bạn nên làm.
Nếu bạn biết cách sử dụng số thập phân làm tròn chính xác, hãy sử dụng gấp đôi. Nhiều đơn đặt hàng của nó về cường độ nhanh hơn, rõ ràng hơn và đơn giản hơn và do đó ít lỗi hơn dễ bị IMHO. Nếu bạn sử dụng đô la và xu (hoặc cần hai chữ số thập phân), bạn có thể nhận được kết quả chính xác cho các giá trị lên đến 70 nghìn tỷ đô la.
Về cơ bản, bạn sẽ không gặp lỗi tròn nếu bạn sửa lỗi bằng cách sử dụng làm tròn approriate.
BTW: Ý nghĩ về các lỗi làm tròn gây khủng bố vào trung tâm của nhiều nhà phát triển, nhưng không phải là ngẫu nhiên lỗi và bạn có thể quản lý chúng một cách dễ dàng.
EDIT: xem xét ví dụ đơn giản này về lỗi làm tròn.
double a = 100000000.01;
double b = 100000000.09;
System.out.println(a+b); // prints 2.0000000010000002E8
Có một số chiến lược làm tròn có thể có. Bạn có thể làm tròn kết quả khi in/hiển thị. ví dụ.
System.out.printf("%.2f%n", a+b); // prints 200000000.10
hoặc tròn kết quả toán học
double c = a + b;
double r= (double)((long)(c * 100 + 0.5))/100;
System.out.println(r); // prints 2.000000001E8
Trong trường hợp của tôi, tôi làm tròn kết quả khi gửi từ máy chủ (bằng văn bản cho một ổ cắm và một tập tin), nhưng sử dụng thói quen của riêng tôi để tránh bất kỳ tạo đối tượng.
Một chức năng vòng chung hơn như sau, nhưng nếu bạn có thể sử dụng printf hoặc DecimalFormat, có thể đơn giản hơn.
private static long TENS[] = new long[19]; static {
TENS[0] = 1;
for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1];
}
public static double round(double v, int precision) {
assert precision >= 0 && precision < TENS.length;
double unscaled = v * TENS[precision];
assert unscaled > Long.MIN_VALUE && unscaled < Long.MAX_VALUE;
long unscaledLong = (long) (unscaled + (v < 0 ? -0.5 : 0.5));
return (double) unscaledLong/TENS[precision];
}
lưu ý: bạn có thể sử dụng BigDecimal để thực hiện làm tròn cuối cùng. esp nếu bạn cần một phương pháp vòng specifc.
+1 cho tiêu đề "Tăng gấp đôi số tiền của tôi" – Marko
Để hiểu tình huống của bạn. Nhưng: tiền mặt và kế toán thích hợp có xu hướng quan trọng đối với các tập đoàn. Vì vậy, làm các vụ kiện cẩu thả. Bạn đang ở một nơi khó khăn: một mặt, khuyên rằng công ty đốt cháy nhiều năm phát triển để sửa chữa những gì dường như là một vấn đề không. Mặt khác, mời các vấn đề lớn xuống đường. Nếu tôi là bạn, tôi sẽ cụm từ nó vào quản lý của tôi theo cách đó, và để họ thực hiện cuộc gọi. Bạn đã có một vấn đề trách nhiệm pháp lý ở đây, và đó là những gì sếp của bạn ở đó. Ghi lại bất kỳ quyết định nào. –
Với những gì @Michael Petrotta nói, anh ấy đúng 100%. Tùy thuộc vào những gì bạn đang làm, họ có thể là vấn đề trách nhiệm lớn đến ống xuống từ quyết định này. Ngoài ra, khuôn khổ này - nó là một khuôn khổ thương mại? Thay vào đó, bạn có thể thuyết phục họ thay đổi thành BigDecimal hay có phiên bản nào không?Nếu không, bạn sẽ cần phải đầu con đường tái cấu trúc gia tăng, đó là một tình huống khủng khiếp nơi bạn đang có - Tôi cảm thấy cho bạn. – aperkins