2014-10-04 16 views
6

Nếu tôi viết mã trong C++:C++ đôi để lâu dài

long long d = 999999998.9999999994; 
cout<<d; 

tôi nhận được kết quả: 999999999 (làm tròn lên)

Nhưng đầu ra của mã này:

long long d = 999999998.9999994994; 
cout<<d; 

999999998 (làm tròn)

Có liên quan gì đến độ chính xác không. Có cách nào tôi có thể thay đổi độ chính xác. Chức năng floor() cũng cho ra cùng một đầu ra.

Tôi cũng nhận thấy rằng nếu tôi gán giá trị 8.9999994994 hoặc 8.9999999994-d (trên biến). Đầu ra là 8.

+0

Bạn có thể thêm rõ ràng 0,5 và truyền gấp đôi thành dài. –

+0

Hỗ trợ C++ 11? Các chữ cái do người dùng định nghĩa có thể hữu ích. – Yakk

+0

@OleksandrVerhun Bạn có thể làm điều này, nhưng nếu mục tiêu của bạn là làm tròn số dấu phẩy động đến số nguyên gần nhất, bạn không nên làm điều này. http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 –

Trả lời

10

999999998.9999999994 là không chính xác biểu diễn trong double, vì vậy giá trị thực tế là một trong hai con số biểu diễn ở hai bên của 999999998.9999999994 - hoặc 999999998.99999988079071044921875 hoặc 999999999 (giả dạng IEEE-754 binary64), được lựa chọn một cách thực hiện xác định. Hầu hết các hệ thống sẽ theo mặc định quanh đến gần nhất, sản xuất 999999999.

Kết quả thực là trên các hệ thống đó khi bạn viết 999999998.9999999994, nó sẽ có hiệu quả chính xác như viết 999999999.0. Do đó chuyển đổi tiếp theo mang lại 999999999 - việc chuyển đổi từ một số dấu phẩy động sang một số nguyên luôn cắt ngắn, nhưng ở đây không có gì để cắt ngắn.

Với 999999998.9999994994, những con số biểu diễn gần nhất là 999999998.999999523162841796875999999998.99999940395355224609375. Hoặc là một trong những sản xuất 999999998 sau khi cắt ngắn. Tương tự, với 8.9999999994, các số có thể đại diện gần nhất là 8.9999999993999999503557774005457758903503417968758.9999999994000017267126168007962405681610107421875 và một số sẽ tạo ra 8 sau khi cắt bớt.

4
long long d = 999999998.9999999994; 

Giá trị gần 999999998.9999999994 rằng double thể đại diện là 999999999.0 - hãy nhớ rằng điểm nổi có độ chính xác hữu hạn;).
Vì vậy, cắt bớt các chữ số thập phân mang lại hiệu quả 999999999 và đó là những gì được lưu trong d.

Sử dụng chữ với L -suffix thực sự dẫn đến 999999998 được lưu trong d - long double có độ chính xác cao hơn.

long long d = 999999998.9999994994; 

Giá trị gần 999999998.9999994994 rằng double thể đại diện thực sự dưới đây 999999999 - khoảng 999999998.999999523 trên máy tính của tôi. Cắt ngắn các vị trí thập phân sau đó mang lại 999999998 và được lưu trữ trong d.

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