[C/C++] So sánh 2 số thực trong C++

Việc so sánh 2 số thực trong C++ đôi khi cho kết quả không mong muốn. Vì các số thực có thể chỉ được lưu gần đúng với

  • Độ chính xác đơn (float): Đây là định dạng nhị phân chiếm 32 bit (4 byte) và phần định trị của nó có độ chính xác 24 bit (tương đương với khoảng 7 chữ số thập phân).
  • Độ chính xác kép (float) Đây là định dạng nhị phân chiếm 64 bit (8 byte) và phần định trị của nó có độ chính xác 53 bit (tương đương với khoảng 16 chữ số thập phân).

Ví dụ hình trên ta gán giá trị (visual studio 2015)

  • 0.7 cho biến float nhưng giá trị thực tế nó nhận được chỉ là 0.699999988
  • 0.7 cho biến double nhưng giá trị thực tế nó nhận được chỉ là 0.69999999999999996

=> biến double có độ chính xác hơn rất nhiều so với float

Ta có chương trình sau

#include <iostream>
#include <limits>

using namespace std;

int main()
{
   float val = 0.7f;
   
   if (val == 0.7)
   {
      cout << "Equal" << endl;
   }
   else
   {
      cout << "Not equal" << endl;
   }
   
   return 0;
}

Kết quả:

Vì sao ?

  • Các số thực được lưu gần đúng
  • Biến val là kiểu float, “0.7” là kiểu double (default hằng số thực trong C++ là kiểu double)

=> nên giá trị thực của biến val và 0.7 khác nhau

=> Cho ra kết quả đúng ta sửa lại

if (val == 0.7f)
{
   cout << "Equal" << endl;
}
else
{
   cout << "Not equal" << endl;
}

=> Lúc này biến val và “0.7f” cùng kiểu float nên có giá trị giống nhau.

Xem về literal hậu tố tại Biến và kiểu dữ liệu

Chú ý :

  • So sánh 2 số thực nên cùng kiểu dữ liệu (cùng float hoặc cùng double)

Sử dụng epsilon

Hai số thực a và b được coi là bằng nhau khi chúng chênh nhau giá trị <= epsilon (đủ nhỏ được định nghĩa trước)

bool isEqual(double a, double b, double epsilon)
{
  return fabs(a - b) <= epsilon;
}

Trong thư viện <limits> của C++ cung cấp :

  • FLT_EPSILON : định nghĩa giá trị epsilon cho số float
  • DBL_EPSILON : định nghĩa giá trị epsilon cho số double
#include <iostream>
#include <limits>
#include <math.h>

using namespace std;

int main()
{
   float val = 0.7f;
   
   //abs hàm lấy giá trị tuyệt đối trong math.h
   if (abs(val - 0.7) <= FLT_EPSILON)
   {
      cout << "Equal" << endl;
   }
   else
   {
      cout << "Not equal" << endl;
   }
   
   return 0;
}

 

Leave A Comment?