Добро пожаловать, Гость
Логин: Пароль: Запомнить меня
  • Страница:
  • 1

ТЕМА: Опасный нюанс WinAVR

Опасный нюанс WinAVR 1 год, 3 мес. назад #1

  • ARV
  • Вне сайта
  • Администратор
  • Постов: 573
  • Репутация: 22
Сегодня я попал на один нюансик WinAVR, который едва не подорвал мою веру в непогрешимость avr-gcc.
Дело было так.
В одном проектике я решил делать промежуточные расчеты в числах с плавающей точкой, т.е. float. Ну а после всех вычислений уже выдавать результат в виде округленного int. И получилось у меня как-то так:
int get_value(void);

int func(void){
  float data;
  data = get_value(void);
  // далее всякие манипуляции с data
  return data;
Вроде бы код - проще пареной репы! А работал удивительно: если функция get_value возвращала числа меньше 82 или больше 100, все вычисления осуществлялись правильно, во всяком случае никакого удивления не вызывали. Но в промежутке более 82 но менее 100 творились чудеса: переменная data получала значение не возвращенное функцией get_value число 92, а что-то типа 1.34Е09 - число с 9 нулями!!! Разумеется, все остальные вычисления шли псу под хвост, и общий результат получался дико неприемлемым.

А оказалось, что для корректной работы требовалось подключить математическую библиотеку libm - без этого глюк устранить никак не получалось! Особо подчеркиваю, что это мне практически повезло, что глюк выплыл в процессе отладки, т.к. проявлялся он для узкого диапазона "входных" чисел, и вполне мог быть такой расклад, что в процессе отладки именно эти странные числа я бы никогда и выбрал... А в реальном проекте обязательно что-то нехорошее вышло бы.

Поэтому, от греха подальше, советую всем, кто использует WinAVR для расчетов с float, и так же, как я, планирует использовать неявное приведение типа получаемых результатов к нужному типу, всегда и безусловно подключать к своему проекту математическую библиотеку libm!
я не ленивый, я энергосберегающий...
Спасибо сказали: kot-69
  • Страница:
  • 1
Время создания страницы: 0.06 секунд