2013-04-25 44 views
44

Tôi đang tìm cách tốt nhất để chuyển đổi một Số thành BigDecimal.Chuyển đổi Số Java thành BigDecimal: cách tốt nhất

Điều này có đủ tốt không?

Number number; 
BigDecimal big = new BigDecimal(number.toString()); 

Chúng ta có thể mất độ chính xác với phương pháp toString() không?

+2

mã của bạn có thể ném 'NumberFormatException' - nếu' number' là 'Double' là Infinity hoặc NaN http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Double .html # toString (double) –

+0

Cảm ơn mẹo! Tôi quên kiểm tra điều này –

Trả lời

32

Điều này là tốt, hãy nhớ rằng việc sử dụng hàm tạo của BigDecimal để khai báo giá trị có thể nguy hiểm khi nó không thuộc loại String. Hãy xem xét dưới đây ...

BigDecimal valDouble = new BigDecimal(0.35); 
System.out.println(valDouble); 

này sẽ không in 0,35, nó sẽ Infact được ...

0.34999999999999997779553950749686919152736663818359375 

Tôi muốn nói giải pháp của bạn có lẽ là an toàn nhất vì lý do đó.

+0

Vâng, tôi đã nhận thấy điều đó. Lo lắng của tôi là về phương thức 'toString()' cho 'Double', tôi đã tự hỏi liệu chúng ta có thể mất chính xác với phương thức này hay không. –

+0

Không, mặc dù bạn sẽ tự nhiên có độ chính xác cao hơn nếu nó là một BigDecimal ở nơi đầu tiên. Nếu nó đối phó với tiền tệ, bạn nên luôn luôn làm cho tất cả mọi thứ BigDecimal. Nếu nó được khai báo là BigDecimal trước khi được cast từ một Double, đó sẽ là giải pháp tốt nhất theo quan điểm của tôi và đưa Double ra khỏi phương trình hoàn toàn. – david99world

16

Chúng ta có thể mất độ chính xác với phương thức toString() không?

Loại ... Cả Float.toString()Double.toString() chỉ xuất số chữ số sau dấu tách thập phân, được yêu cầu cho đầu ra duy nhất tương ứng với giá trị float hoặc kép.

Để sử dụng ví dụ 0,35 trong câu trả lời david99world của, hãy xem xét đoạn mã sau:

BigDecimal bd1 = new BigDecimal(0.35); 

Number n = 0.35; 
BigDecimal bd2 = new BigDecimal(n.toString()); 

System.out.println(bd1); 
System.out.println(bd2); 

Một sự mong đợi trực quan có thể là hai trường hợp BigDecimal là giống hệt nhau, nhưng sản lượng cho thấy rằng họ không phải là:

0.34999999999999997779553950749686919152736663818359375 
0.35 

Dòng đầu tiên là giá trị chính xác của số double, vì 0,35 không thể được biểu diễn chính xác. Dòng thứ hai là 0,35, vì không cần thêm số thập phân để biểu thị giá trị khác biệt. Ví dụ. tuyên bố 0.34999999999999997779553950749686919152736663818359375 == 0.35 sẽ đánh giá là true.

Điều này thực sự không mất chính xác khi tạo BigDecimal, độ không chắc chắn đã có trong giá trị "nguồn" của bạn. Vấn đề là thay vào đó các giá trị rời rạc có thể sử dụng ví dụ: một giá trị float hoặc double là nguồn không nhất thiết sẽ được biểu diễn bằng giá trị tương đương chính xác trong cá thể BigDecimal.

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