Я использую LinearProgressIndicator для визуального отображения обратного отсчета времени и запуска функции через определенные промежутки времени. Я делаю это, обновляя свойство value
LinearProgressIndicator, используя переменную состояния _progress
, которая уменьшается на 0,01 каждые 100 миллисекунд.
Когда я устанавливал условия, основанные на двух десятичных знаках или даже на 0 if (_progress == 0.75)
, я обнаружил, что условия пропускаются, потому что значение _progress быстро становится гораздо большей дробью, которая не соответствует моему условию (например, 0,7502987777777). Я предполагаю, что это неотъемлемая проблема работы с двойниками, но тогда возникает вопрос: как лучше всего справиться с этим, если вы хотите запускать действия на основе значения _progress? Мой подход заключается в расширении условий - например if (_progress > 0.75 && _progress < 0.76)
.
Любые советы/советы будут оценены. Спасибо.
При работе со значениями с плавающей запятой вы часто не можете полагаться на строгое равенство. Вместо этого вы должны проверить, находится ли ваше значение с плавающей запятой в пределах определенного допуска от желаемого значения. Один подход:
bool closeTo(double value1, double value2, [double epsilon = 0.001]) =>
(value1 - value2).abs() <= epsilon;
if (closeTo(_progress, 0.75)) {
// Do something.
}
(package:matcher имеет аналогичную функцию closeTo для сопоставления значений в тестах.)
Возможно, поскольку значения с плавающей запятой являются плавающими, ваш допуск должен зависеть от величины значений.
В вашем случае вам также следует серьезно подумать о том, чтобы избегать значений с плавающей запятой для внутреннего состояния: используйте значения с фиксированной запятой, умножая все на 100 и используя вместо этого int
s. То есть пусть _progress
будет int
, уменьшайте его на 1 каждые 100 мс, и тогда вы можете напрямую и точно сравнивать с 75 или другими значениями. Это также будет иметь то преимущество, что не будет накапливаться ошибка с плавающей запятой, когда вы многократно уменьшаете _progress
. Если вам нужно представить _progress
пользователю или передать его LinearProgressIndicator
, используйте вместо этого _progress / 100
.
Доооо!! Это имеет гораздо больше смысла. Я просто изменил _progress на int, начиная со 100 и уменьшая его на 1 каждые 100 миллисекунд, а затем использовал _progress/100 в LinearProgressIndicator. Это позволило мне использовать целые числа в операторе if
if (_progress == 75)
, и это сработало как шарм. Спасибо, что нашли время, чтобы помочь мне думать иначе. Очень признателен.