Добрый день. Помогите разобраться с задачей. Есть компилятор codevision есть переменная типа Float, я в цикле прибавляю к ней 0,01 и сравниваю с заданным значением другой переменной float а результата никакого. В протэусе проверяю и видно что у переменной появляются левые значения.
Например 0+0,01+0,01+0,01+0,01=0,04000999
Почему так ??????????????????????????? Подскажите пожалуйста!
Последний раз редактировалось mas_43 Ср апр 04, 2012 18:36:31, всего редактировалось 1 раз.
************************************************* Если обозначить машинный порядок Мр, а математический — р, то связь между ними ыразится такой формулой:
Мр = р + 64.
Итак, машинный порядок смещен относительно математического на 64 единицы и имеет только положительные значения. При выполнении вычислений с плавающей точкой процессор это смещение учитывает. *************************************************
Не в этом. Дело в том, что числа, точно представленные в десятичной арифметике, могут быть не представимы точно в двоичной. Кроме того, из-за конечной длины мантиссы при сложении, когда происходит выравнивание порядков, младшие разряды меньшего числа "уплывают" за пределы разрядной сетки. Мы можем до посинения к 1 миллиаду прибавлять 0.0000001 - результат не изменится.
Даже если забыть по числа с плавающей запятой, а взять с фиксированной. Пусть будет дробная часть в 4 разряда, т.е. самое маленькое число мы можем представить 0.0625 Казалось бы - 4 знака после запятой, но это в десятичной. Вот 0,0626 мы уже не можем записать. Следующее будет 0.125, потом - 0.1875 и так далее.
Господа! Разница на два порядка - катастрофа? 2mas_43: CVAVR довольно интересно обращается с плавающей запятой. Уж так написана библиотека. (За что, уверен, поминают ее автора недобрым словом.) Я в свое время набарахтался. Ныне очень аккуратно с ней обращаюсь. При первой же возможности вообще не использую.
На два порядка - т.е. приблизительно в 100 раз -- конечно, катастрофа. А при соблюдении несложных правил, основанных на знании float арифметики, она не так и страшна. Например, при суммировании большого числа данных для уменьшения потери точности рекомендуется провести сортировку их и суммировать, начиная с самых меньших по абс. величине. Такие маленькие хитрости делают жизнь не такой мрачной, какой она иногда может казаться.
1. При программировании микроконтроллеров плавающую запятую лучше не использовать. В 99.9% случаев достаточно фиксированной запятой - т.е., просто работы с числами, умноженными на 10ⁿ.
2. Если очень хочется использовать float, лучше не использовать float.
3. Вещественные числа никогда не сравнивают "в лоб", т.е., оператором "==". В 99.99% случаев они не будут равны из-за описанной выше ошибки представления / конечной точности вычислений. Адекватное решение - проверять на попадание в некий интервал.
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
При разработке микроконтроллерных устройств измерения, контроля, а также автоматической регулировки технологических параметров просто не обойтись без использования функции float. Ниже привожу фрагмент программы использования данной функции. В прикрепленном файле Proteus наглядно показана работа функции float при задании и измерении тока. Вы же имея перед глазами приведенный пример можете адаптировать его к собственным нуждам.
//******* Глобальные переменные ******* float ka=0.009785; //коэффициент пересчета тока для 10А unsigned int integer_a; //целая часть числа функции измерения канала тока long int xa,ya,za; //Дробная часть функции вычислений тока float result_a; //результат преобразования задания тока float temp_a,*ba; //Промежуточный результат вычислений тока
//********* Вычисление данных АЦП измерения тока ********* result_a= adc_data[0]*ka; //результат преобразования АЦП тока ADC0 integer_a= floor(result_a); //функция floor возвращает ближайшее целое число temp_a= modf(result_a,ba); //функция modf разделяет число на целую и дробную части temp_a= temp_a*1000; //округление до тысячных (темп*1000) //Стандартный цикл математических вычислений xa = temp_a/100; //Десятые temp_a= temp_a-xa*100; ya=temp_a/10; //Сотые temp_a = temp_a-ya*10; za = temp_a; //Тысячные
_________________ На каждого Моцарта есть свой Сальери.
При разработке микроконтроллерных устройств измерения, контроля, а также автоматической регулировки технологических параметров просто не обойтись без использования функции float
... если аффтар не знает про числа с фиксированной запятой и не умеет адаптировать формулы под них. Практически любую формулу можно адаптировать так, что она влезет в целочисленные вычисления. Данные от DS18B20 Вы тоже прямым текстом на 0.0625 умножать будете?
bl, bh - данные из датчика, соответственно младший и старший байт. Получаем значение температуры до второго знака, умноженное на 10:
Не буквоедства ради, а только ради истины : Float это вообще-то тип данных, а не функция... YS Во-первых да, float - не функция, а тип данных.
Господа! С Вами мне все понятно, но меня удивляет другое: как же Вы можете давать советы, если сами не знаете что float – это не только тип данных но и математическая функция. Просмотрите “Стандартные библиотечные функции ” CV-AVR, (подраздел “Математические функции”) и вопросы отпадут сами собой. Теперь по выводу данных от температурного датчика DS1820. Здесь формула ещё проще. Используя библиотечные функции датчика, программа вывода укладывается всего в две строчки без использования float и прочих старших и младших байтов (хотя и здесь можно применить функцию float – но просто не имеет смысла перегружать программу).
_________________ На каждого Моцарта есть свой Сальери.
Просмотрите “Стандартные библиотечные функции ” CV-AVR, (подраздел “Математические функции”)
Да, мы знаем, что CVAVR нарушает добавляет много правил в стандарт С. И, как и все адекватные люди, советуем по-возможности как можно меньше использовать нестандартные элементы.
Почитайте стандарт ANSI C. Последний на сегодняшний момент - С99. А чего там напридумывали создатели CVAVR, я не знаю.
И да, я почитал мануал по CVAVR, раздел 4.4, "Mathematical functions". Нету там функции float. По крайней мере, я не нашел. Может, Вам попался кривой русский перевод? Или я плохо смотрел?
_________________ Разница между теорией и практикой на практике гораздо больше, чем в теории.
Мы с Вами пользуемся одним и тем же мануалом. Так вот в разделе 4.4, "Mathematical functions" на странице 104 функция float встречается 3 раза, на странице 105 – 10 раз, а на странице 106 – 11 раз. Просмотрите мануал более внимательно
_________________ На каждого Моцарта есть свой Сальери.
4.4, "Mathematical functions" на странице 104 функция float встречается 3 раза
Похоже вы чего-то путаете. Я хоть CV не пользовался ни разу, но могу точно сказать - такой функции быть не должно. И посмотрел документ, никакой подобной функции не увидел. Это только тип данных, который используется в других функциях.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения