როგორ შევამოწმოთ ორი მყარი წერტილის (float) თანასწორობა?
sobes.tech AI
პასუხი AI-სგან
დაცული არ არის პირდაპირ შედარება ოპერატორით ==, რადგან წარმოდგენის და რაუნდინგის სპეციფიკების გამო. ამის ნაცვლად, უნდა შემოწმდეს, არის თუ არა მნიშვნელობათა სხვაობის აბსოლუტური მნიშვნელობა მცირე ზღვარის (epsilon) ფარგლებში.
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
მრეწველად უფრო სტაბილური მიდგომა ითვალისწინებს ურთიერთმნიშვნელოვან შეცდომას, განსაკუთრებით როდესაც შედარება ხორციელდება ძალიან დიდ ან ძალიან პატარა რიცხვებზე:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// შედარება განსხვავების ზომის გათვალისწინებით
// მნიშვნელოვანია, რომ ცალკე განიხილოს ნული და უსასრულო შემთხვევები
if (a == b) {
return true; // მოიცავს შემთხვევებს, სადაც a=b (შეიცავს უსასრულო და NaN, თუ ისინი თანხვედრაში არიან – რაც NaN-ისთვის არ არის, მაგრამ უსასრულოსთვის არის)
}
float absolute_difference = std::abs(a - b);
float max_abs = std::max(std::abs(a), std::abs(b));
if (max_abs < epsilon) {
return absolute_difference < epsilon; // ორივე რიცხვი ახლოს არის ნულთან
} else {
return absolute_difference / max_abs < epsilon; // ურთიერთმნიშვნელოვანი განსხვავების შედარება
}
}
epsilon არჩევანი დამოკიდებულია საჭირო სიზუსტეზე და შედარების მნიშვნელობების დიაპაზონზე. std::numeric_limits<float>::epsilon() წარმოადგენს ყველაზე მცირე რიცხვს, რომლისთვისაც შესრულდება 1.0 + epsilon განსხვავება 1.0-დან.
მნიშვნელოვანია გახსოვდეთ, რომ NaN (Number არა) თანმიმდევრულად ყოველთვის false-ს აბრუნებს, მათ შორის nan == nan. თუ საჭიროა NaN-ის დამუშავება, ეს უნდა გაკეთდეს ცალკე.