Неточное отображение

Обсуждаем контроллеры компании Atmel.
Ответить
zepar
Открыл глаза
Сообщения: 79
Зарегистрирован: Ср май 28, 2014 12:55:56

Неточное отображение

Сообщение zepar »

Доброй ночи! Использую CV AVR, Proteus. Складываю float, результат помещаю в массив char с помощью sprintf и вывожу на LCD через библиотеку командой lcd_puts. Иногда отображаются неточные результаты. Например, 43.9+5 = 48.900001. Или 5/2 = 2, 499998. Притом, если перезапустить выполнение через протеус и проделать тоже самое заново, иногда отображается на ура. Кто тут жульничает и из-за чего?

Добавлено: после пару перезапусков 43.9+5 = 48.899997
Аватара пользователя
A_AVL
Потрогал лапой паяльник
Сообщения: 311
Зарегистрирован: Чт фев 10, 2011 10:22:20
Откуда: Беларусь
Контактная информация:

Re: Неточное отображение

Сообщение A_AVL »

Так и должно быть. Эти числа нельзя точно представить в двоичном виде. Загуглите "погрешность представления чисел с плавающей точкой"
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: Неточное отображение

Сообщение Pink-Pank »

A_AVL писал(а):Эти числа нельзя точно представить в двоичном виде.


Согласен, но у человека одна и та же операция дает разные погрешности. Предположить, что программа, записанная в память контроллера, считает каждый раз по разному - как-то абсурдно.. Думаю, копать нужно в сторону Протеуса.
Fucking static initialization order fiasco
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Неточное отображение

Сообщение ibiza11 »

согласен. неточность связана именно с ограничениями float, а разные результаты одной и той же операции только эмулятор.
Ставим плюсы: )
Аватара пользователя
Муркиз
Друг Кота
Сообщения: 25758
Зарегистрирован: Пн фев 09, 2009 22:19:49
Откуда: Когда-то был прекрасный город для людей

Re: Неточное отображение

Сообщение Муркиз »

Обязательно округлять надо с заданной точностью при преобразовании типов чисел для последующих операций.
Аватара пользователя
__Alexander
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Вт сен 11, 2007 10:27:08
Откуда: Киев

Re: Неточное отображение

Сообщение __Alexander »

протеус так лагать не может по определению, это всё выдумки sprintf, который нормальные люди не используют.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

Re: Неточное отображение

Сообщение Pink-Pank »

И что же там в sprintf записали? генератор случайных чисел? Там заложен какой-то алгоритм, который каждый раз считает одинаково.
Fucking static initialization order fiasco
Аватара пользователя
A_AVL
Потрогал лапой паяльник
Сообщения: 311
Зарегистрирован: Чт фев 10, 2011 10:22:20
Откуда: Беларусь
Контактная информация:

Re: Неточное отображение

Сообщение A_AVL »

Pink-Pank писал(а):Согласен, но у человека одна и та же операция дает разные погрешности. Думаю, копать нужно в сторону Протеуса.

Погрешность представления float- 1E-7. Все числа у него индицируются в пределах этой погрешности (7 знаков). То что числа преобразуются без округления и разный результат преобразования, зависящий от положения звёзд на небе-это к библиотекам cvavr. IAR, например, своими библиотеками преобразует корректно и с округлением, но и весят эти библиотеки по 8к и жрут под 1к озу.
zepar
Открыл глаза
Сообщения: 79
Зарегистрирован: Ср май 28, 2014 12:55:56

Re: Неточное отображение

Сообщение zepar »

__Alexander писал(а):протеус так лагать не может по определению, это всё выдумки sprintf, который нормальные люди не используют.


А чем нынче пользуются нормальные люди ? Как мне отобразить float на LCD ?
Аватара пользователя
A_AVL
Потрогал лапой паяльник
Сообщения: 311
Зарегистрирован: Чт фев 10, 2011 10:22:20
Откуда: Беларусь
Контактная информация:

Re: Неточное отображение

Сообщение A_AVL »

В вашем случае - или искать стороннюю нормальную библиотеку sprintf или ftoa, или самостоятельно округлять полученный результат до семи знаков. Больше никак, IMHO.
zepar
Открыл глаза
Сообщения: 79
Зарегистрирован: Ср май 28, 2014 12:55:56

Re: Неточное отображение

Сообщение zepar »

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: Неточное отображение

Сообщение A_AVL »

Ну по идее, 43.999+1 должно быть равно 44.99899?-знак вопроса восьмая цифра, которую вы не привели. так вот, округлять нужно уже преобразованный через sprintf результат до седьмого знака. Вся эта попытка "округлить" float непосредственно у меня ни к чему не привела(и не может ни к чему привести). Использовать нормальные библиотеки от IAR я не стал по причине занимаемой памяти, как и заморачиваться с округлением результата. Но если бы пришлось - то единственный на мой взгляд путь это преобразовать полученную в строке мантиссу из 8 цифр в signed long и затем округлить это число по правилам математики. А потом опять же через sprintf вывести мантиссу отдельно, а порядок отдельно и получить "красивое" число.
zepar
Открыл глаза
Сообщения: 79
Зарегистрирован: Ср май 28, 2014 12:55:56

Re: Неточное отображение

Сообщение zepar »

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: Неточное отображение

Сообщение A_AVL »

Так я ж выам выкладывал библиотеку перевода без использования stdio.h
viewtopic.php?f=57&t=104581
Останется прикрутить к ней округление мантиссы.
zepar
Открыл глаза
Сообщения: 79
Зарегистрирован: Ср май 28, 2014 12:55:56

Re: Неточное отображение

Сообщение zepar »

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: Неточное отображение

Сообщение A_AVL »

Непонятно. У меня такого не аблюдается. Может с округлением что? Выводится как 0, а на самом деле там не 0?
Ответить

Вернуться в «AVR»