Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Уменьшить код и освоить СИ
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Andrew_k5
На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.
Dima_G
Цитата(Andrew_k5 @ Oct 27 2009, 13:44) *
На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.

поищите информацию про Fixed point
ARMik
Может BCD использовать. unsigned char 9,9 максимум получится. Мало, берите 16бит
sergeeff
А что мешает все делать с целыми числами? Например, вместо 12,5 работать с числом 125 и положение запятой учесть только при выводе.
SSerge
Во-первых, можно все переменные отмасштабировать так, чтобы иметь дело с целыми числами.
Во-вторых, можно использовать представление с фиксированной точкой, фактически работа по-прежнему идёт как с целыми числами, просто Вы мысленно представляете себе где находится точка, отделяющая целую часть от дробной и куда она перемещается, например после операции умножения.
Даже если работать с 64-разрядными целыми это получается быстрее, чем плавающая арифметика на Меге.
В том и другом случае приходится держать "в уме" масштабирующие коэффициенты. А для вывода целая и дробная части выводятся как отдельные целые числа, разделённые точкой (или запятой, по вкусу).
Если счёта много то выгоднее масштабировать на степень двойки, если мало счёта, а ввода/вывода в десятичном представлении много, тогда удобнее двоично-десятичное представление (каждые 4 бита хранят число от 0 до 9), или представление по основанию 100, каждый байт хранит числа от 0 до 99.

Кстати, экономии программной памяти всё это не так уж и сильно поможет, плавающая арифметика всё равно делается вызовами подпрограмм.
А вот отказ от функции printf(), или хотя бы от той её части, что работает с плавающей точкой, экономит и флэшь и ОЗУ очень хорошо.
Andrew_k5
Цитата(sergeeff @ Oct 27 2009, 14:51) *
А что мешает все делать с целыми числами? Например, вместо 12,5 работать с числом 125 и положение запятой учесть только при выводе.

Как это реализовать, вывод на LCD через sprintf. Плаваю в Си очень сильно, подскажите книжечку по Си для атмела в связке с CodeVision.
Палыч
Цитата(Andrew_k5 @ Oct 27 2009, 16:09) *
Как это реализовать
Вы хотите знать кать вывести целое, имеющее множитель 10, как вещественное используя sprintf ? Например, так:
Код
unsigned int I;   // Умноженное на 10
sprintf(Buffer, "%d,%d", I/10, I%10);

или как-то так:
Код
unsigned int I;   // Умноженное на 10
unsigned int Temp;
Temp= I/10;
sprintf(Buffer, "%d,%d", Temp, I-Temp);
Andrew_k5
Происходит потеря точности:
float CenaZaPoezd;
int CenaLitr;


CenaLitr=125;
CenaZaPoezd=CenaLitr/10;

Результат 12, а не 12,5!!!
Получается надо везде сперва присваивать, а потом умножать, те CenaZaPoezd=CenaLitr;CenaZaPoezd=CenaZaPoezd/10; я не думаю что так код уменьшится сильно.
Палыч
Цитата(Andrew_k5 @ Oct 27 2009, 16:33) *
Происходит потеря точности:
CenaLitr=125;
CenaZaPoezd=CenaLitr/10;
Нет. Вы что-то не понимаете. У Вас перменная CenaLitr равна 125. Эта переменная имеет множитель 10. Т.е. в действительности 12 целых и 5 десятых. Вам всего-то и нужно, что вывести её на дисплей, вставив в нужном месте десятичную запятую. Т.е. вместо "125" необходимо вывести "12,5". И - всё!
Dog Pawlowa
Цитата(Палыч @ Oct 27 2009, 18:11) *
Вам всего-то и нужно

printf("%3u,%lu", x/10, x%10);
Andrew_k5
Цитата(Dog Pawlowa @ Oct 27 2009, 18:22) *
printf("%3u,%lu", x/10, x%10);

Обязательно попробую, x%10 - это остаток от деления на 10?, а что такое %lu.
Dog Pawlowa
Цитата(Andrew_k5 @ Oct 27 2009, 17:40) *
Обязательно попробую, x%10 - это остаток от деления на 10?, а что такое %lu.

Это вывод этого остатка, только l - лишняя, это у меня как раз переменная на экране было long, забыл убрать.
Должно быть %u.
Andrew_k5
Спасибо за ответы, есть еще необходимость реализации 2-го UARTa. Как это сделать, можно RX общим сделать, а что с TX, переадресовать на другой дискретный выход? UARTы работают не одновременно.
Dima_G
Цитата(Andrew_k5 @ Oct 27 2009, 17:09) *
Как это реализовать, вывод на LCD через sprintf. Плаваю в Си очень сильно, подскажите книжечку по Си для атмела в связке с CodeVision.

Рекомендую не пользоваться функциями типа sprintf, printf и тд тк у вас и так не хватает ресурсов, а эти функции очень прожорливые sad.gif

Напишите свою реализацию под вашу задачу - выйдет гораздо лучше
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.