реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Уменьшить код и освоить СИ, Не хватает памяти программ
Andrew_k5
сообщение Oct 27 2009, 10:44
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 77
Регистрация: 15-02-07
Из: Днепропетровск
Пользователь №: 25 387



На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Oct 27 2009, 11:39
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(Andrew_k5 @ Oct 27 2009, 13:44) *
На меге 16 не хватает памяти для программы, все переменные которые могут принимать дробные значения использую тип float, может есть способ использовать другой тип данных, допустим надо вывести 12,5 , может можно unsigned char каким то образом 125 вывести как 12,5.

поищите информацию про Fixed point
Go to the top of the page
 
+Quote Post
ARMik
сообщение Oct 27 2009, 11:46
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 103
Регистрация: 22-02-07
Пользователь №: 25 588



Может BCD использовать. unsigned char 9,9 максимум получится. Мало, берите 16бит
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Oct 27 2009, 11:51
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



А что мешает все делать с целыми числами? Например, вместо 12,5 работать с числом 125 и положение запятой учесть только при выводе.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Oct 27 2009, 11:54
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Во-первых, можно все переменные отмасштабировать так, чтобы иметь дело с целыми числами.
Во-вторых, можно использовать представление с фиксированной точкой, фактически работа по-прежнему идёт как с целыми числами, просто Вы мысленно представляете себе где находится точка, отделяющая целую часть от дробной и куда она перемещается, например после операции умножения.
Даже если работать с 64-разрядными целыми это получается быстрее, чем плавающая арифметика на Меге.
В том и другом случае приходится держать "в уме" масштабирующие коэффициенты. А для вывода целая и дробная части выводятся как отдельные целые числа, разделённые точкой (или запятой, по вкусу).
Если счёта много то выгоднее масштабировать на степень двойки, если мало счёта, а ввода/вывода в десятичном представлении много, тогда удобнее двоично-десятичное представление (каждые 4 бита хранят число от 0 до 9), или представление по основанию 100, каждый байт хранит числа от 0 до 99.

Кстати, экономии программной памяти всё это не так уж и сильно поможет, плавающая арифметика всё равно делается вызовами подпрограмм.
А вот отказ от функции printf(), или хотя бы от той её части, что работает с плавающей точкой, экономит и флэшь и ОЗУ очень хорошо.


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post
Andrew_k5
сообщение Oct 27 2009, 13:09
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 77
Регистрация: 15-02-07
Из: Днепропетровск
Пользователь №: 25 387



Цитата(sergeeff @ Oct 27 2009, 14:51) *
А что мешает все делать с целыми числами? Например, вместо 12,5 работать с числом 125 и положение запятой учесть только при выводе.

Как это реализовать, вывод на LCD через sprintf. Плаваю в Си очень сильно, подскажите книжечку по Си для атмела в связке с CodeVision.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 27 2009, 13:22
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(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);
Go to the top of the page
 
+Quote Post
Andrew_k5
сообщение Oct 27 2009, 13:33
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 77
Регистрация: 15-02-07
Из: Днепропетровск
Пользователь №: 25 387



Происходит потеря точности:
float CenaZaPoezd;
int CenaLitr;


CenaLitr=125;
CenaZaPoezd=CenaLitr/10;

Результат 12, а не 12,5!!!
Получается надо везде сперва присваивать, а потом умножать, те CenaZaPoezd=CenaLitr;CenaZaPoezd=CenaZaPoezd/10; я не думаю что так код уменьшится сильно.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 27 2009, 14:11
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Andrew_k5 @ Oct 27 2009, 16:33) *
Происходит потеря точности:
CenaLitr=125;
CenaZaPoezd=CenaLitr/10;
Нет. Вы что-то не понимаете. У Вас перменная CenaLitr равна 125. Эта переменная имеет множитель 10. Т.е. в действительности 12 целых и 5 десятых. Вам всего-то и нужно, что вывести её на дисплей, вставив в нужном месте десятичную запятую. Т.е. вместо "125" необходимо вывести "12,5". И - всё!
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 27 2009, 14:22
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Палыч @ Oct 27 2009, 18:11) *
Вам всего-то и нужно

printf("%3u,%lu", x/10, x%10);


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Andrew_k5
сообщение Oct 27 2009, 14:40
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 77
Регистрация: 15-02-07
Из: Днепропетровск
Пользователь №: 25 387



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

Обязательно попробую, x%10 - это остаток от деления на 10?, а что такое %lu.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Oct 27 2009, 14:51
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



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

Это вывод этого остатка, только l - лишняя, это у меня как раз переменная на экране было long, забыл убрать.
Должно быть %u.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Andrew_k5
сообщение Oct 27 2009, 14:56
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 77
Регистрация: 15-02-07
Из: Днепропетровск
Пользователь №: 25 387



Спасибо за ответы, есть еще необходимость реализации 2-го UARTa. Как это сделать, можно RX общим сделать, а что с TX, переадресовать на другой дискретный выход? UARTы работают не одновременно.

Сообщение отредактировал Andrew_k5 - Oct 27 2009, 14:57
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Oct 27 2009, 15:08
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(Andrew_k5 @ Oct 27 2009, 17:09) *
Как это реализовать, вывод на LCD через sprintf. Плаваю в Си очень сильно, подскажите книжечку по Си для атмела в связке с CodeVision.

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

Напишите свою реализацию под вашу задачу - выйдет гораздо лучше
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 23:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01476 секунд с 7
ELECTRONIX ©2004-2016