- vừa được xem lúc

Xử lý lỗi làm tròn Floating point numbers trong C++

0 0 11

Người đăng: Tờ Mờ Sáng học Lập trình

Theo Viblo Asia

ĐỊNH NGHĨA

Floating point numbers hay còn gọi là số có dấu phảy động.

Trong lập trình thi đấu, các kiểu dữ liệu dấu phảy động thường được sử dụng nhất đó là kiểu dữ liệu double 64 bit và một extension trong trình biên dịch g++, đó là kiểu dữ liệu long double 80 bit.

Trong đa số các trường hợp, chỉ cần sử dụng double là đủ. Còn kiểu dữ liệu long double đương nhiên sẽ có độ chính xác cao hơn vì nó sử dụng nhiều bit hơn.

Độ chính xác cần thiết cho 1 bài toán thường sẽ được ghi rõ trong đề bài. Vì vậy các bạn hãy lưu ý đọc kỹ để sử dụng kiểu dữ liệu phù hợp.

3.png

Cách dễ nhất để chỉ định số các số thập phân sẽ in ra đó là sử dụng hàm printf(). Ví dụ:

printf("%.9f\n", x);

sẽ giúp chúng ta in ra được giá trị của x với 9 số ở phần thập phân.

VẤN ĐỀ

‼️ Một vấn đề kinh điển nhất khi làm việc với floating point numbers đó là có những số mà máy tính sẽ không thể biểu diễn đầy đủ các số ở phần thập phân của nó, từ đó dẫn đến việc làm tròn không chính xác.

Ví dụ đoạn code sau có thể sẽ khiến các anh em mới học lập trình cảm thấy vô cùng cảm lạnh 🥶

// Đọc đến đây có thể các bạn sẽ nghĩ x = 0.9 + 0.1 = 1 đúng không?
double x = 0.3 * 3 + 0.1; // Nhưng khi ta in giá trị của x với 20 số ở phần thập phân, Kết quả in ra lại là: 0.99999999999999988898
printf("%.20f\n", x); 

Chính vì lỗi làm tròn số mà mình đã nói ở trên, nên giá trị thực của x sẽ nhỏ hơn số 1 một chút, trong khi giá trị mà chúng ta thực sự mong muốn là giá trị 1.

Vì vậy, sẽ rất rủi ro nếu chúng ta so sánh các floating point numbers sử dụng toán tử == Vì có thể nhìn bằng mắt thường sẽ thấy chúng bằng nhau, nhưng thực tế máy tính lại cho ra kết quả khác, vì lỗi làm tròn.

VẬY THÌ PHẢI XỬ LÝ THẾ NÀO BÂY GIỜ? 🤔

✅ Cách tốt hơn để so sánh các floating point numbers đó là: kiểm tra điều kiện, nếu số a trừ số b mà ra 1 giá trị rất nhỏ (thường là nhỏ hơn 10⁻⁹), thì chúng ta sẽ coi như 2 số đó bằng nhau.

// Ở đây hàm abs() là hàm tính giá trị tuyệt đối, để đảm bảo (a-b) không bị âm
if (abs(a-b) < 1e-9) { // Kết luận a và b bằng nhau
}

Các bạn có thể tham khảo series video "Lên trình Thuật toán - Lập trình thi đấu 🏆" mà mình đang làm trên Youtube tại đây.

8.png

Hi vọng kiến thức này hữu ích với bạn. Hẹn gặp lại 👋

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học lập trình game cần những gì?

Lập trình game là làm gì. Các ngôn ngữ các bạn có thể sử dụng để lập trình game : C, C++, C#, Java, Python,... Các bước cơ bản để lập trình game. . Hiển thị: Đã là game thì hiển thị không thể thiếu, lúc đầu các bạn chỉ làm cho phần hiển thị thật đơn giản, các bạn đừng quá chú tâm vào việc làm sao ch

0 0 44

- vừa được xem lúc

[MFC] Http request with winsock2.h

Giới thiệu. Xin chào, trong bài này mình sẽ giới thiệu 1 số lưu ý khi sử dụng thư viện winsock2.h (thư viện window socket) sử dụng trong window app. Đầu tiên, bạn sẽ dễ dàng search được 1 ví dụ cụ thể trên document của winsock2.

0 0 35

- vừa được xem lúc

Design parttern

Builder. 1. Ý tưởng. Builder là một mẫu thiết kế sáng tạo cho phép bạn xây dựng các đối tượng phức tạp theo từng bước.

0 0 32

- vừa được xem lúc

Kỹ thuật viết mã nguồn hiệu quả

Kỹ thuật viết mã nguồn hiệu quả? Hôm nay bài viết này mình không đề cập tới thuật toán, hãy coi như rằng chúng ta đã có thuật toán tốt nhất có thể và bây giờ chúng ta phải làm gì để có thể tăng tính hiệu quả của code. Bài viết này mình sẽ lấy ngôn ngữ lập trình C/C++ để minh họa về các hàm, các thao

0 0 38

- vừa được xem lúc

Singleton Design pattern

Singleton Design pattern. 1. Vấn đề. - Ý tưởng:.

0 0 35

- vừa được xem lúc

So sánh Python và C++

Cuộc tranh luận giữa Python và C ++ là một chủ đề hấp dẫn vì cả hai ngôn ngữ lập trình đều rất khác nhau về cú pháp, tính đơn giản, cách sử dụng và cách tiếp cận tổng thể để lập trình. Vì vậy, mọi người cảm thấy khó khăn khi lựa chọn ngôn ngữ lập trình nào để học.

0 0 38