Страница 1 из 1

Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 05:48:16
Dr. Alex
Есть маленький вопросик, как вывести на LCD или семисегментник число с плавающей точкой. Например результат умножения числа 12 на константу 3.14?

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 06:09:20
Enigm
Разбить число на составляющие, например через стринг. и выводим на ЛСД
Ну а путем проверки где есть точка, зажигаем нужную точку на семисегметнике..

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 06:37:29
pokk
Умножаешь константу на 3.14*100=314 потом производишь с ней математические операции 12*314=3768 и при выводе на индикатор (или разложения по разрядам) учитываешь что последнии 2 цифры это дробная часть и перед ней надо поставить точку.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 09:15:24
Dr. Alex
pokk писал(а):Умножаешь константу на 3.14*100........
Пожалуй самое дельное выражение... А как быть с результатом деления? Например делим константу 100 на любое число, возьмём 13?

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 09:30:26
ARV
какая разница, как получен 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);
}
но лично я, если уж проект таков, что идет работа с отжирающими память и быстродействие float-ами, просто использовал бы стандартные функции семейства printf с возможностями форматированного вывода float-ов.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 09:47:35
pokk
А как быть с результатом деления? Например делим константу 100 на любое число, возьмём 13?
Опять таки домножить константу на 100 (или другую всё зависит от точности которую надо) а потом поделить
т.е 100*100/13=769 ну а при выводе на индикатор поставить точку перед последними двумя числами.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 09:52:22
Dr. Alex
А изначально, в корне, нельзя решить вопрос?

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 10:07:31
Dr. Alex
pokk писал(а):Опять таки домножить константу на 100 (или другую всё зависит от точности которую надо).
Хорошо. А два числа типа int при делении дадут целое число????

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 10:40:53
ARV
Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
можно: изучить Си по книгам.
Dr. Alex писал(а):А два числа типа int при делении дадут целое число????
см. выше - любите книгу, источник знаний!

любые операции с int дадут в результате int

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт апр 30, 2015 10:45:36
Dr. Alex
Всем спасибо!

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт май 07, 2015 15:16:44
chief
Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Чт май 07, 2015 16:02:44
DX168B
Никогда не парился, ибо не приходилось пихать код ногами в AVR микроконтроллер (в PIC приходилось один раз)

Код: Выделить всё

uint8_t strbuf[DISP_MAX_STRINGSIZE];
***
sprintf((char*)str_buff, "%1.2fV", (double)(displayData->battVoltage * 0.01f)); // Легко задается нужная точность и форматированный вывод.
 

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 06:02:44
Kasha-bread
chief писал(а):
Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.
чтобы памяти не жрало, надо переходить на ассемблер. Но тогда требуется "искусство программирования", а не тупое подключение библиотек.

Например я программировал на 8-разрядном 580ик80 в ассемблере на числах с плавающей запятой (для 8-ми знаков после запятой и до 100-й степени, т.е. типичное 64-битное число с пл.точкой) и поэтому проблем с выводом на дисплей, какой-бы то нибыло, у меня меня не возникало.
И при этом успевало на 2 МГц обслуживать клавиатуру и дисплей. ))

Для начала в этом вопросе рекомендую почитать книжку "8085 subroutines" которая есть в переводе на русский язык.
Вопросы (почти все) отпадут сами собой. Правда эта книжка не для "погроммистов" нынешнего поколения.

Модератору Аен (написавшему мне письмо) - ну чо, это тоже "словесный понос"? )) Сам ты "погроммист", вот и удаляешь, потому что тебе это кажется оскорбительным, как сосунку в "погроммировании".

Добавил.
Т.е. Вы передергиваете факты.
Нарушение Правил форума п. 5 и п. 4 Общих положений Правил.
aen

Изображение

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 08:41:31
Siarzhuk
DX168B писал(а):

Код: Выделить всё

sprintf((char*)str_buff, "%1.2fV", (double)(displayData->battVoltage * 0.01f)); // Легко задается нужная точность и форматированный вывод.
А battVoltage в данном случае float? В противном случае немножко не понятно использование здесь float константы 0.01f с последуюшим приведением результата к double. ИМХО можно "сэкономить байты кода™" домножая на double константу 0.01 - тогда и приводить не понадобится - результат операции будет уже в double. Хотя, конечно, в зависимости от целевой платформы могут быть эффекты уже на размере исполняемого кода. :-)

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 08:54:03
Аlex
А battVoltage в данном случае float? В противном случае немножко не понятно использование здесь float константы 0.01f с последуюшим приведением результата к double.
Скорее - наоборот, понятно приведение к double, если battVoltage - целочисленный. А вот если бы battVoltage был типом с плавающей точкой, то приведение не совсем оправдано.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 08:59:23
ARV
Kasha-bread писал(а):но тогда требуется "искусство программирования"
искусство программирования умерло, осталось ремесло.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 10:24:17
Kasha-bread
chief писал(а):
Dr. Alex писал(а):А изначально, в корне, нельзя решить вопрос?
Разрешить компилятору работать с числами с плавающей точкой и, как писал ARV, использовать форматированный вывод. Памяти жрет немеряно и время для обработки тоже.
))))
Что такое сейчас 2 кБ ?
20 лет назад этого хватало обслуживать 64-битные числа с плавающей точкой (9-разрялов после запятой и до 100-й степени), на 8-ми разрядном процессоре 580ик80 (i8080) на 2 МГц.

Изучайте ассемблер.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 10:46:37
eess9
Уважаемый Kasha-bread, ARV прав. Возьмите Cortex-M4, например, и начинайте писать для него на ассемблере. Это же маразм. 8-ми битные MCU еще долго будут умирать, но это не повод перестать двигаться со временем.

Re: Вывод числа с плавающей точкой - Си

Добавлено: Пт май 08, 2015 16:52:42
Siarzhuk
Аlex писал(а):Скорее - наоборот, понятно приведение к double, если battVoltage - целочисленный. А вот если бы battVoltage был типом с плавающей точкой, то приведение не совсем оправдано.
Простите зануду - это я до суффикса f в константе прицепился - которой делает её float типом. ;-) А oперация приведения к double применяется уже к произведению int на float, которое и так имеет тип float:

Код: Выделить всё

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);
В том собственно и вопрос - имеет-ли перемножение float-ов с последуюшим приведением к double какое нибудь преимущество перед простым перемножением double-ов - размер программы, быстродействие и т.п.