Вывод числа с плавающей точкой - Си
Есть маленький вопросик, как вывести на LCD или семисегментник число с плавающей точкой. Например результат умножения числа 12 на константу 3.14?
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
- Реклама
Разбить число на составляющие, например через стринг. и выводим на ЛСД
Ну а путем проверки где есть точка, зажигаем нужную точку на семисегметнике..
Ну а путем проверки где есть точка, зажигаем нужную точку на семисегметнике..
- Сообщения: 574
- Зарегистрирован: Вт ноя 02, 2010 17:46:37
Умножаешь константу на 3.14*100=314 потом производишь с ней математические операции 12*314=3768 и при выводе на индикатор (или разложения по разрядам) учитываешь что последнии 2 цифры это дробная часть и перед ней надо поставить точку.
Пожалуй самое дельное выражение... А как быть с результатом деления? Например делим константу 100 на любое число, возьмём 13?pokk писал(а):Умножаешь константу на 3.14*100........
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
какая разница, как получен float - в результате деления, умножения или еще каким-то образом?!
суть в следующем
но лично я, если уж проект таков, что идет работа с отжирающими память и быстродействие float-ами, просто использовал бы стандартные функции семейства printf с возможностями форматированного вывода float-ов.
суть в следующем
Код: Выделить всё
void sprint_float(char *str, float f){
char tmp[10];
int i = f; // спорно: f может быть огромным числом, но чисто для примера пойдет
itoa(str, i, 10);
strcat(str, ".");
i = abs(f - i)*100; // 2 знака после запятой
itoa(tmp, i, 10);
strcat(str, tmp);
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Сообщения: 574
- Зарегистрирован: Вт ноя 02, 2010 17:46:37
Опять таки домножить константу на 100 (или другую всё зависит от точности которую надо) а потом поделитьА как быть с результатом деления? Например делим константу 100 на любое число, возьмём 13?
т.е 100*100/13=769 ну а при выводе на индикатор поставить точку перед последними двумя числами.
А изначально, в корне, нельзя решить вопрос?
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Хорошо. А два числа типа int при делении дадут целое число????pokk писал(а):Опять таки домножить константу на 100 (или другую всё зависит от точности которую надо).
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
можно: изучить Си по книгам.Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
см. выше - любите книгу, источник знаний!Dr. Alex писал(а):А два числа типа int при делении дадут целое число????
любые операции с int дадут в результате int
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Всем спасибо!
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
- Сообщения: 397
- Зарегистрирован: Ср сен 19, 2007 09:21:04
Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Никогда не парился, ибо не приходилось пихать код ногами в AVR микроконтроллер (в PIC приходилось один раз)
Код: Выделить всё
uint8_t strbuf[DISP_MAX_STRINGSIZE];
***
sprintf((char*)str_buff, "%1.2fV", (double)(displayData->battVoltage * 0.01f)); // Легко задается нужная точность и форматированный вывод.
I am DX168B and this is my favourite forum on internet!
чтобы памяти не жрало, надо переходить на ассемблер. Но тогда требуется "искусство программирования", а не тупое подключение библиотек.chief писал(а):Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Например я программировал на 8-разрядном 580ик80 в ассемблере на числах с плавающей запятой (для 8-ми знаков после запятой и до 100-й степени, т.е. типичное 64-битное число с пл.точкой) и поэтому проблем с выводом на дисплей, какой-бы то нибыло, у меня меня не возникало.
И при этом успевало на 2 МГц обслуживать клавиатуру и дисплей. ))
Для начала в этом вопросе рекомендую почитать книжку "8085 subroutines" которая есть в переводе на русский язык.
Вопросы (почти все) отпадут сами собой. Правда эта книжка не для "погроммистов" нынешнего поколения.
Модератору Аен (написавшему мне письмо) - ну чо, это тоже "словесный понос"? )) Сам ты "погроммист", вот и удаляешь, потому что тебе это кажется оскорбительным, как сосунку в "погроммировании".
Добавил.
Т.е. Вы передергиваете факты.
Нарушение Правил форума п. 5 и п. 4 Общих положений Правил.
aen
- Вложения
-
- 1.PNG
- (37.08 КБ) 1521 скачивание
Последний раз редактировалось Kasha-bread Пт май 08, 2015 10:19:59, всего редактировалось 1 раз.
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
А battVoltage в данном случае float? В противном случае немножко не понятно использование здесь float константы 0.01f с последуюшим приведением результата к double. ИМХО можно "сэкономить байты кода™" домножая на double константу 0.01 - тогда и приводить не понадобится - результат операции будет уже в double. Хотя, конечно, в зависимости от целевой платформы могут быть эффекты уже на размере исполняемого кода.DX168B писал(а):Код: Выделить всё
sprintf((char*)str_buff, "%1.2fV", (double)(displayData->battVoltage * 0.01f)); // Легко задается нужная точность и форматированный вывод.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Скорее - наоборот, понятно приведение к double, если battVoltage - целочисленный. А вот если бы battVoltage был типом с плавающей точкой, то приведение не совсем оправдано.А battVoltage в данном случае float? В противном случае немножко не понятно использование здесь float константы 0.01f с последуюшим приведением результата к double.
искусство программирования умерло, осталось ремесло.Kasha-bread писал(а):но тогда требуется "искусство программирования"
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
))))chief писал(а):Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Что такое сейчас 2 кБ ?
20 лет назад этого хватало обслуживать 64-битные числа с плавающей точкой (9-разрялов после запятой и до 100-й степени), на 8-ми разрядном процессоре 580ик80 (i8080) на 2 МГц.
Изучайте ассемблер.
За ваши деньги - пошлю куда угодно (в пределах СССР)
Уважаемый Kasha-bread, ARV прав. Возьмите Cortex-M4, например, и начинайте писать для него на ассемблере. Это же маразм. 8-ми битные MCU еще долго будут умирать, но это не повод перестать двигаться со временем.
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Простите зануду - это я до суффикса f в константе прицепился - которой делает её float типом.Аlex писал(а):Скорее - наоборот, понятно приведение к double, если battVoltage - целочисленный. А вот если бы battVoltage был типом с плавающей точкой, то приведение не совсем оправдано.
Код: Выделить всё
battVoltage // тип int
0.01f // float
(battVolatge * 0.01f) // float
double(battVolatge * 0.01f) // double
Код: Выделить всё
battVoltage // тип int
0.01 // double
0.01 * battVolatge // double
// т.е. возвращаясь к исходной строчке:
sprintf((char*)str_buff, "%1.2fV", 0.01 * displayData->battVoltage);
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 


