Полная версия этой страницы:
Уменьшить код и освоить СИ
Andrew_k5
Oct 27 2009, 10:44
На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.
Dima_G
Oct 27 2009, 11:39
Цитата(Andrew_k5 @ Oct 27 2009, 13:44)

На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.
поищите информацию про Fixed point
Может BCD использовать. unsigned char 9,9 максимум получится. Мало, берите 16бит
sergeeff
Oct 27 2009, 11:51
А что мешает все делать с целыми числами? Например, вместо 12,5 работать с числом 125 и положение запятой учесть только при выводе.
SSerge
Oct 27 2009, 11:54
Во-первых, можно все переменные отмасштабировать так, чтобы иметь дело с целыми числами.
Во-вторых, можно использовать представление с фиксированной точкой, фактически работа по-прежнему идёт как с целыми числами, просто Вы мысленно представляете себе где находится точка, отделяющая целую часть от дробной и куда она перемещается, например после операции умножения.
Даже если работать с 64-разрядными целыми это получается быстрее, чем плавающая арифметика на Меге.
В том и другом случае приходится держать "в уме" масштабирующие коэффициенты. А для вывода целая и дробная части выводятся как отдельные целые числа, разделённые точкой (или запятой, по вкусу).
Если счёта много то выгоднее масштабировать на степень двойки, если мало счёта, а ввода/вывода в десятичном представлении много, тогда удобнее двоично-десятичное представление (каждые 4 бита хранят число от 0 до 9), или представление по основанию 100, каждый байт хранит числа от 0 до 99.
Кстати, экономии программной памяти всё это не так уж и сильно поможет, плавающая арифметика всё равно делается вызовами подпрограмм.
А вот отказ от функции printf(), или хотя бы от той её части, что работает с плавающей точкой, экономит и флэшь и ОЗУ очень хорошо.
Andrew_k5
Oct 27 2009, 13:09
Цитата(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
Oct 27 2009, 13:33
Происходит потеря точности:
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, 14:22
Цитата(Палыч @ Oct 27 2009, 18:11)

Вам всего-то и нужно
printf("%3u,%lu", x/10, x%10);
Andrew_k5
Oct 27 2009, 14:40
Цитата(Dog Pawlowa @ Oct 27 2009, 18:22)

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

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

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

Напишите свою реализацию под вашу задачу - выйдет гораздо лучше
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.