Russian Qt Forum
Апрель 23, 2024, 16:43 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: float == float  (Прочитано 4125 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« : Апрель 17, 2015, 10:30 »

Привет, друзья!
Знаю, что вопрос избитый, но хотелось бы его рассмотреть относительно моей ситуации.

Имеется текстовый файл, в который записаны некоторые вещественные числа с точностью до 6 знака. Хотел бы узнать, правомерно ли их сравнивать через operator==.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апрель 17, 2015, 10:43 »

Используй
Код
C++ (Qt)
bool qFuzzyCompare(float p1, float p2)
и не парся)
Записан

Qt 5.11/4.8.7 (X11/Win)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Апрель 17, 2015, 11:05 »

Для даблов написано
Цитировать
Note that comparing values where either p1 or p2 is 0.0 will not work. The solution to this is to compare against values greater than or equal to 1.0.
Предлагают
Код:
// Instead of comparing with 0.0
qFuzzyCompare(0.0,1.0e-200); // This will return false
// Compare adding 1 to both values will fix the problem
qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true

К флоатам это тоже относится? Что-то мне это не особо нравится.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Апрель 17, 2015, 11:52 »

Используй
Код
C++ (Qt)
bool qFuzzyCompare(float p1, float p2)
и не парся)
А давайте все-таки попарымся Улыбающийся Что же делает то fuzzy (чудо великих "троллей")
Код
C++ (Qt)
Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2)
{
   return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2)));
}
 
Возьмем 2 числа, напр 100.0f и 100.001f (100 + 1.0e-3f). Получаем

1.0e-3f * 1.0e+5f <= 100.0f
100.0f <= 100.0f  // return true

Во как, здесь не ловит даже третий знак. То наверное сделали для работников UI где точность до пыкселя  Улыбающийся

Имеется текстовый файл, в который записаны некоторые вещественные числа с точностью до 6 знака. Хотел бы узнать, правомерно ли их сравнивать через operator==.
Кого "их"? Считали из файла 2 числа, можем ли их сравнивать? Рез-том будет только "точное" сравнение. Т.е. равные числа останутся равными после записи в файл и чтения из него. Однако числа что были неравными могут оказаться равными, и наоборот, разница между ними может увеличиться. Конечно Вы все это знали, так что, дружок, формулируйте вопрос яснее  Улыбающийся
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #4 : Апрель 17, 2015, 15:36 »

Однако числа что были неравными могут оказаться равными, и наоборот, разница между ними может увеличиться.
Мне вчера сказали подобную фразу, что и побудило меня создать тему.

Вот есть у меня текстовый файл, в котором записано 4 числа:
Код:
0,123456 0,123456 0,123456 0,123456
Я через текстовый поток их присваиваю своему массиву float numbers[4].

Я полагаю, что перевод из текста во float происходит по одинаковому алгоритму и у меня будет выполняться условие numbers[m] == numbers[n]. Не понимаю, как между ними может увеличиться разница? "числа что были неравными могут оказаться равными" вы уверены, что такое бывает?
« Последнее редактирование: Апрель 17, 2015, 15:41 от __Heaven__ » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Апрель 17, 2015, 16:02 »

Я полагаю, что перевод из текста во float происходит по одинаковому алгоритму и у меня будет выполняться условие numbers[m] == numbers[n]. Не понимаю, как между ними может увеличиться разница? "числа что были неравными могут оказаться равными" вы уверены, что такое бывает?
Пример (возьмем округления до 2 знаков чтобы меньше писать)
Цитировать
1.244 ->  1.24
1.243 ->  1.24
Вот неравные стали равными

Цитировать
1.24499999999 ->  1.24
1.24500000000 ->  1.25
Вот разница между ними увеличилась.

В этих примерах используется "бухгалтерское" округление, но и с любым другим - проблемы все те же. Если в текст и назад - примириться с потерей точности. Чтобы избежать - пишите в бинарный файл (тот же QDataStream)



Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Апрель 17, 2015, 17:08 »

Меня больше интересует text => float.
Нет ли какого-то влияния случайности на перевод одного и того же текста в флоат?
То есть, всегда ли в пределах одного процесса "1.24" превращается в 1.24000000001?
Я бы мог сравнивать текст, но мне интереснее перегнать оба значения в float и уже после сравнить.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Апрель 17, 2015, 17:19 »

Меня больше интересует text => float.
Нет ли какого-то влияния случайности на перевод одного и того же текста в флоат?
То есть, всегда ли в пределах одного процесса "1.24" превращается в 1.24000000001?
При переводе текста не знаю, а вот при выполнении расчетов - точно нет, за это получал.

Я бы мог сравнивать текст, но мне интереснее перегнать оба значения в float и уже после сравнить.
Нормальное, стандартное решение - сравнивать с заданной точностью
Код
C++ (Qt)
const float eps_float = 1.0e-5f;
if (fabs(f1 - f2) <= eps_float) return true; // полагаем что равны
Так все равно делать придется, и много раз. Поэтому неясно в чем Ваша цель и каких приключений Вы ищете
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.113 секунд. Запросов: 22.