Неточное отображение
Неточное отображение
Доброй ночи! Использую CV AVR, Proteus. Складываю float, результат помещаю в массив char с помощью sprintf и вывожу на LCD через библиотеку командой lcd_puts. Иногда отображаются неточные результаты. Например, 43.9+5 = 48.900001. Или 5/2 = 2, 499998. Притом, если перезапустить выполнение через протеус и проделать тоже самое заново, иногда отображается на ура. Кто тут жульничает и из-за чего?
Добавлено: после пару перезапусков 43.9+5 = 48.899997
Добавлено: после пару перезапусков 43.9+5 = 48.899997
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
Так и должно быть. Эти числа нельзя точно представить в двоичном виде. Загуглите "погрешность представления чисел с плавающей точкой"
- Pink-Pank
- Опытный кот
- Сообщения: 721
- Зарегистрирован: Ср июн 11, 2014 09:43:13
- Откуда: США
- Контактная информация:
Re: Неточное отображение
A_AVL писал(а):Эти числа нельзя точно представить в двоичном виде.
Согласен, но у человека одна и та же операция дает разные погрешности. Предположить, что программа, записанная в память контроллера, считает каждый раз по разному - как-то абсурдно.. Думаю, копать нужно в сторону Протеуса.
Fucking static initialization order fiasco
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Неточное отображение
согласен. неточность связана именно с ограничениями float, а разные результаты одной и той же операции только эмулятор.
Ставим плюсы: )
- Муркиз
- Друг Кота
- Сообщения: 25758
- Зарегистрирован: Пн фев 09, 2009 22:19:49
- Откуда: Когда-то был прекрасный город для людей
Re: Неточное отображение
Обязательно округлять надо с заданной точностью при преобразовании типов чисел для последующих операций.
- __Alexander
- Потрогал лапой паяльник
- Сообщения: 335
- Зарегистрирован: Вт сен 11, 2007 10:27:08
- Откуда: Киев
Re: Неточное отображение
протеус так лагать не может по определению, это всё выдумки sprintf, который нормальные люди не используют.
- Pink-Pank
- Опытный кот
- Сообщения: 721
- Зарегистрирован: Ср июн 11, 2014 09:43:13
- Откуда: США
- Контактная информация:
Re: Неточное отображение
И что же там в sprintf записали? генератор случайных чисел? Там заложен какой-то алгоритм, который каждый раз считает одинаково.
Fucking static initialization order fiasco
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
Pink-Pank писал(а):Согласен, но у человека одна и та же операция дает разные погрешности. Думаю, копать нужно в сторону Протеуса.
Погрешность представления float- 1E-7. Все числа у него индицируются в пределах этой погрешности (7 знаков). То что числа преобразуются без округления и разный результат преобразования, зависящий от положения звёзд на небе-это к библиотекам cvavr. IAR, например, своими библиотеками преобразует корректно и с округлением, но и весят эти библиотеки по 8к и жрут под 1к озу.
Re: Неточное отображение
__Alexander писал(а):протеус так лагать не может по определению, это всё выдумки sprintf, который нормальные люди не используют.
А чем нынче пользуются нормальные люди ? Как мне отобразить float на LCD ?
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
В вашем случае - или искать стороннюю нормальную библиотеку sprintf или ftoa, или самостоятельно округлять полученный результат до семи знаков. Больше никак, IMHO.
Re: Неточное отображение
A_AVL писал(а):В вашем случае - или искать стороннюю нормальную библиотеку sprintf или ftoa, или самостоятельно округлять полученный результат до семи знаков. Больше никак, IMHO.
Лучше самостоятельно. Но как определить до какого знака именно ? Если брать стабильно 7 знаков, то получается так:
43.999+1 = 44.99899
P.S Я видел когда-то давно, что там сравнивают с числом и еще +- e = 0.00001. Что-то в этом роде. И если, с учетом погрешности e условие верно, то результат округляют.
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
Ну по идее, 43.999+1 должно быть равно 44.99899?-знак вопроса восьмая цифра, которую вы не привели. так вот, округлять нужно уже преобразованный через sprintf результат до седьмого знака. Вся эта попытка "округлить" float непосредственно у меня ни к чему не привела(и не может ни к чему привести). Использовать нормальные библиотеки от IAR я не стал по причине занимаемой памяти, как и заморачиваться с округлением результата. Но если бы пришлось - то единственный на мой взгляд путь это преобразовать полученную в строке мантиссу из 8 цифр в signed long и затем округлить это число по правилам математики. А потом опять же через sprintf вывести мантиссу отдельно, а порядок отдельно и получить "красивое" число.
Re: Неточное отображение
A_AVL писал(а):Ну по идее, 43.999+1 должно быть равно 44.99899?-знак вопроса восьмая цифра, которую вы не привели. так вот, округлять нужно уже преобразованный через sprintf результат до седьмого знака. Вся эта попытка "округлить" float непосредственно у меня ни к чему не привела(и не может ни к чему привести). Использовать нормальные библиотеки от IAR я не стал по причине занимаемой памяти, как и заморачиваться с округлением результата. Но если бы пришлось - то единственный на мой взгляд путь это преобразовать полученную в строке мантиссу из 8 цифр в signed long и затем округлить это число по правилам математики. А потом опять же через sprintf вывести мантиссу отдельно, а порядок отдельно и получить "красивое" число.
Спасибо. Я пришел к выводу, что нужно переводить float в строку самостоятельно без использование sprintf. Можно проконтролировать процесс и отказаться от stdio.h.
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
Так я ж выам выкладывал библиотеку перевода без использования stdio.h
viewtopic.php?f=57&t=104581
Останется прикрутить к ней округление мантиссы.
viewtopic.php?f=57&t=104581
Останется прикрутить к ней округление мантиссы.
Re: Неточное отображение
A_AVL писал(а):Так я ж выам выкладывал библиотеку перевода без использования stdio.h
viewtopic.php?f=57&t=104581
Останется прикрутить к ней округление мантиссы.
Да, разобрался. Вот еще такой вопрос: в калькуляторе нужно ввести защиту от деления на ноль. Вот такие условия всегда ложные:
Код: Выделить всё
1)case '/': if(x1==0) {lcd_putchar('E'); } else Push(y1/x1); break;
2)case '/': if(x1==0.0) {lcd_putchar('E'); } else Push(y1/x1); break;
3)case '/': if(x1==0.0f) {lcd_putchar('E'); } else Push(y1/x1); break;
Можно подумать, дело не в этом? Но такое условие срабатывает:
Код: Выделить всё
case '/': if(x1==5) {lcd_putchar('E'); } else Push(y1/x1); break;
Ах да, x1 - тип float.
- A_AVL
- Потрогал лапой паяльник
- Сообщения: 311
- Зарегистрирован: Чт фев 10, 2011 10:22:20
- Откуда: Беларусь
- Контактная информация:
Re: Неточное отображение
Непонятно. У меня такого не аблюдается. Может с округлением что? Выводится как 0, а на самом деле там не 0?