Цикл не прекращается, WTF?

Простейшие вопросы в области инженерной разработки
Ответить
Аватара пользователя
toshas
assistant
assistant
Сообщения: 105
Зарегистрирован: 05 апр 2009, 22:45
Версия LabVIEW: 9.0
Благодарил (а): 13 раз
Поблагодарили: 7 раз
Контактная информация:

Цикл не прекращается, WTF?

Сообщение toshas »

Добрый день!

Простой код. Версия LV2014f1.
Если считать целыми (+1), то все нормально.
Если использовать сравнение "больше либо равно", то все нормально.
А вот если делать сравнение "равно?" и считать десятые, то цикл не останавливается.
Если добавить индикатор на сумму и включить побольше знаков,
то проскакивают какие-то далекие цифры (условно 10,0000000356124).
Откуда они ?

В чем может быть косяк ?

Спасибо!
Вложения
test_strange.png
test_strange.png (12.75 КБ) 2333 просмотра
mixail_
user
user
Сообщения: 93
Зарегистрирован: 05 июн 2013, 08:58
Версия LabVIEW: 13
Контактная информация:

Re: Цикл не прекращается, WTF?

Сообщение mixail_ »

Такой результат получаете потому что при работе с числами с плавающей точкой существует погрешность представления числа. То есть то что вы видите как 10.0 на самом деле будет, например, 10.0000000001, поэтому числа с плавающей точкой так не сравнивают. Как один из вариантов для сравнения таких чисел if(abs(my_num - expected_my_num) < eps)) DoSmth(); eps - точность с которой нужно чтобы совпали числа для того чтобы их можно было назвать равными или просто в вашем случае поставить >=
AndreyDmitriev

Activity Professionalism Tutorials Gold Black
VIP
VIP
Сообщения: 1338
Зарегистрирован: 03 фев 2010, 00:42
Награды: 6
Версия LabVIEW: 6.1 - 2024
Откуда: Германия
Благодарил (а): 1 раз
Поблагодарили: 44 раза
Контактная информация:

Re: Цикл не прекращается, WTF?

Сообщение AndreyDmitriev »

toshas писал(а):проскакивают какие-то далекие цифры (условно 10,0000000356124).
Откуда они ?
Числа с плавающей точкой хранятся в памяти компьютера в восьми байтах (если говорить о двойной точности). Восемь байт это 64 бита и это даёт нам ровно 18446744073709551615 возможных значений. При этом 52 бита относятся к мантиссе, 11 - к порядку и ещё один отвечает за знак. Теперь представьте себе числовую прямую от -1 на десять в трёхсотой степени до +1 в трёхсотой (точнее, диапазон, который вы можете хранить во float +/-1.79E+308, а самое маленькое число, ближайшее к нулю +/-4.94E–324). Понятно, что на этой прямой мы имеем бесконечное множество вещественных чисел. Но в нашем распоряжении лишь 18446744073709551615 возможных значений. Таким образом понятно, что для некоторых чисел не будет существовать представления float, посколько множество возможных значений ограничено. Формат float так устроен, что расстояние между шагами сетки растёт по мере удаления от нуля сетка она более густая для чисел с малыми порядками и более редкая — для чисел с большими порядками. И вот так получилось, что, скажем, 0.01 точно в узел сетки не попадает - вместо этого там хранится 0,0100000000000000002, отсюда и ошибки сравнения.
Blackman

Activity
leader
leader
Сообщения: 932
Зарегистрирован: 17 янв 2016, 15:02
Награды: 1
Версия LabVIEW: 6.1,8.5,20

Re: Цикл не прекращается, WTF?

Сообщение Blackman »

Примеры сравнения чисел с плавающей запятой в :labview:
Comparing Floating-Point Numbers
http://www.ni.com/white-paper/7612/en/
Аватара пользователя
toshas
assistant
assistant
Сообщения: 105
Зарегистрирован: 05 апр 2009, 22:45
Версия LabVIEW: 9.0
Благодарил (а): 13 раз
Поблагодарили: 7 раз
Контактная информация:

Re: Цикл не прекращается, WTF?

Сообщение toshas »

Спасибо за разъяснения!
Ответить

Вернуться в «Для чайников»