2012-08-24 42 views
18

Tại sao nó rằng khi tôi làm như sau ...Cần giúp đỡ làm tròn đến 2 chữ số thập phân

Math.Round(0.75, 1, MidpointRounding.AwayFromZero) 

tôi nhận được 0,8

nhưng khi tôi làm như sau ...

Math.Round(0.575, 2, MidpointRounding.AwayFromZero) 

Tôi không nhận được 0,58. Thay vào đó tôi nhận được 0,57. Tôi muốn bất cứ điều gì đó là 5 và lên làm tròn lên, vì vậy 0,575 nên được 0,58.

+0

[Câu trả lời đầu tiên trong câu hỏi này] (http://stackoverflow.com/q/5641616/62576) sẽ giúp trả lời câu hỏi này. –

+0

@KenWhite: Tôi không chắc chắn nó sẽ. Vấn đề là do toán học thực làm tròn '.575' đến hai chữ số thập phân từ 0 sẽ cho' .58' nhưng đây không phải là kết quả quan sát được. Nó liên quan đến việc biểu diễn các bài thơ nổi trong trường hợp này. – Chris

+0

@ Chris: Bạn nói đúng. :-) Tôi chủ yếu sử dụng Delphi, và nó Round() xử lý những thứ như thế này chỉ tốt cho hầu hết các phần. Tôi chỉ cần kiểm tra trong C#, mặc dù, và có thể nhìn thấy vấn đề. –

Trả lời

30

Vấn đề sẽ là bạn không thể đại diện cho 0.575 chính xác như một số dấu phẩy động nhị phân (ví dụ: một đôi). Mặc dù tôi không biết chính xác nó có vẻ như đại diện gần nhất có lẽ chỉ là một chút thấp hơn và do đó, khi làm tròn nó sử dụng các đại diện thực sự và vòng xuống.

Nếu bạn muốn tránh vấn đề này thì hãy sử dụng loại dữ liệu thích hợp hơn. decimal sẽ làm những gì bạn muốn:

Math.Round(0.575M, 2, MidpointRounding.AwayFromZero) 

Kết quả: 0.58

Lý do mà 0,75 làm điều đúng là nó rất dễ dàng để biểu diễn trong dấu chấm động nhị phân vì nó là đơn giản 1/2 + 1/4 (tức là 2^-1 + 2^-2). Nói chung, bất kỳ tổng quyền hạn hữu hạn nào của hai có thể được biểu diễn trong dấu phẩy động nhị phân. Trường hợp ngoại lệ là khi quyền hạn của 2 phạm vi quá lớn một phạm vi (ví dụ: 2^100 + 2 không chính xác được thể hiện).

Chỉnh sửa để thêm:

Formatting doubles for output in C# có thể quan tâm quan trọng để hiểu tại sao nó khó khăn như vậy để hiểu rằng 0,575 không phải là thực sự 0,575. Các DoubleConverter trong câu trả lời được chấp nhận sẽ cho thấy rằng 0,575 như một chuỗi chính xác là 0.5749999999999999555910790149937383830547332763671875 Bạn có thể thấy từ lý do này làm tròn cho 0,57.

+2

Cảm ơn tất cả các bạn. Tôi chuyển đôi của tôi thành một số thập phân và nó thực hiện điều đó. Cảm ơn! –

2

Nguyên nhân là do thiếu độ chính xác với số đôi/số thập phân (tức là - chức năng sẽ không luôn là cho kết quả bạn mong đợi).

Xem liên kết sau: MSDN on Math.Round

Dưới đây là trích dẫn liên quan:

Do mất độ chính xác có thể dẫn đến từ đại diện cho các giá trị thập phân như số dấu chấm động hoặc thực hiện phép toán số học trên nổi giá trị điểm, trong một số trường hợp, phương thức Round (Double, Int32, MidpointRounding) có thể không xuất hiện để làm tròn các giá trị trung điểm như được chỉ định bởi tham số chế độ.Điều này được minh họa trong ví dụ sau, trong đó 2.135 được làm tròn thành 2.13 thay vì 2.14.Đây xảy ra bởi vì nội bộ phương thức nhân giá trị bằng 10digits và phép nhân eration trong trường hợp này bị mất chính xác.

7

Phương pháp System.Math.Round sử dụng cấu trúc Double, như những người khác đã chỉ ra, dễ bị lỗi chính xác của dấu phẩy động. Giải pháp đơn giản tôi tìm thấy cho vấn đề này khi tôi gặp phải đó là sử dụng phương pháp System.Decimal.Round, mà không gặp phải vấn đề tương tự và không đòi hỏi redifining biến của bạn như số thập phân:

Decimal.Round(0.575, 2, MidpointRounding.AwayFromZero) 

Kết quả: 0.58

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