|
Гашение незначащих нулей, кто как делает? |
|
|
|
Aug 31 2008, 10:55
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Пока вижу два варианта вывода числа на ЖКИ с гашением незначащих нулей: Код #include <stdlib.h> div_t dtmp; char str_tmp[6]; str_tmp[5] = 0; OborotiZaMin = (OborotiZaMinConst + (PPeriod >> 1)) / PPeriod;
#if 0
dtmp = div(OborotiZaMin, 10); str_tmp[4] = dtmp.rem + '0'; dtmp = div(dtmp.quot, 10); str_tmp[3] = dtmp.rem + '0'; dtmp = div(dtmp.quot, 10); str_tmp[2] = dtmp.rem + '0'; dtmp = div(dtmp.quot, 10); str_tmp[1] = dtmp.rem + '0'; str_tmp[0] = dtmp.quot + '0'; // Гашение незначащих нулей for (i = 0; i < 4; ++i) if (str_tmp[i] == '0') str_tmp[i] = ' '; else break;
#else i = 0; dtmp = div(OborotiZaMin, 10000); if (dtmp.quot != 0) str_tmp[i++] = dtmp.quot + '0';
dtmp = div(dtmp.rem, 1000); if (i || (dtmp.quot != 0)) str_tmp[i++] = dtmp.quot + '0'; dtmp = div(dtmp.rem, 100); if (i || (dtmp.quot != 0)) str_tmp[i++] = dtmp.quot + '0'; dtmp = div(dtmp.rem, 10); if (i || (dtmp.quot != 0)) str_tmp[i++] = dtmp.quot + '0'; str_tmp[i++] = dtmp.rem + '0'; str_tmp[i] = 0; #endif // LCD_Write Дабы на ЖКИ небыло такого, например "0750", а было такое "750". Какой алгоритм используете?
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
 |
Ответов
|
Aug 31 2008, 20:08
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Ну и до кучи - чтобы все варианты были и чтобы было из чего выбирать. Ведь критерии могут быть разными - если действительно нужно максимальное быстродейстиве (ascii протоколы, например) или минимальный код - тогда лучше всего асм-вариант с умножениями, приведенный Rst7 либо вычитания степеней 10 (где-то я уже приводил свой вариант "без восстановления остатка", когда вычитаются десятки тысяч, потом добавляются единицы тысяч, потом вычитаются сотни и добавляются десятки - каждый раз порогом есть переход через 0 и после этого назад вычитаемое не добавляется - код ещё немного короче и немного быстрее). Если в программе деление всё равно нужно в других местах (уже линкуется и ещё одно использование на размер не влияет) и преобразование нужно только для пользовательского интерфейса (медленного по сути), то itoa по коду не проигрывает (а то и выигрывает), а его тормознутость не мешает. Ну а если кроме "лишних полтора килобайта не жалко" (если без плавающих форматов и переменных ширин полей и прочих режко используемых возможностей, про которые не все и знают, то fprintf тянет где-то столько), не хочется компоновать вывод, вручную соображая форматирование - от перемешивания строк и чисел и включая усечение вывода приведенных вариантов до, скажем, 3 знаков, то printf ничем не хуже. Причём в зависимости от инструмента sprintf (требующий опять таки врукопашную выделять буфер и потом его копировать куда надо) можно отложить и использовать fprintf avr-gcc Код #include <stdio.h> #include <lcd.h>
int lcd_file_putc(char ch, FILE * stream) { (void) stream; lcd_putchar(ch); return 0; }
FILE lcd_file = FDEV_SETUP_STREAM(lcd_file_putc, 0, _FDEV_SETUP_WRITE); #define flcd (&lcd_file)
... // тут и с гашением, и без гашения, и с фиксированной шириной поля, и с переменной // - как угодно fprintf_P( flcd, PSTR("%d 0x%04X"), -20121, 0xBEEF); А если ещё и через терминалку общение всё равно идёт Код int console_putc(char ch, FILE * stream) { (void) stream; uart_putchar(ch); return 0; }
int console_getc(FILE * stream) { (void) stream; return uart_getchar(); }
FILE console_file = FDEV_SETUP_STREAM(console_putc, console_getc, _FDEV_SETUP_RW); #define fconsole (&console_file)
void report_ex_time(const prog_char *header, const prog_char *comment, uint32_t cpu_ticks) { uint32_t ex_time = (cpu_ticks * CPU_TICK_SCALE + 128) / 256; // CPU ticks to us if (comment) fprintf_P(fconsole, PSTR("%-38S = %6luus (%S)\n"), header, ex_time, comment); else fprintf_P(fconsole, PSTR("%-38S = %6luus\n"), header, ex_time); } То и сам fprintf уже не тянет карман, а удобства хватает. В конце концов у какой-нибудь зачуханной меги32 ресурсов - почитай как у "Электроники-60" в неплохой комплектации, а за мегу128 я и не говорю.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 1 2008, 13:01
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
У меня сделано два отдельных преобразования: целое в распакованное двоично-десятичное (здесь никаких хитростей нет, просто последовательно вычитаем 10000, 1000, 100 и т.д.) и двоично-десятичное в семисегментный код. Вот на этом этапе и гасятся нули. CODE // // Перекодировка в 7-сегментные цифры // // Input: // R24:R25 - указатель на массив цифр (6 байт) // R22 - признак гашения ведущих нулей // // используются: // R18 //
BCDto7Segm:ldi r18, 6 mov r26, r24 mov r27, r25 clt sbrc r22, 0 set ; уст. T - гашение ведущих нулей conv: ldi r30, lo8(SegmTable) ldi r31, hi8(SegmTable) ld r0, X brtc addx ; если не гасим нули, то получить 7-сегментный код tst r0 ; если 0 breq cont ; то продолжить clt ; иначе - прекратить гашение нулей sub r24, r26 neg r24 dec r24 ; в r24 - позиция последнего погашенного символа addx: add r30, r0 adc r31, r1 lpm st X, r0 cont: adiw r26, 1 dec r18 brne conv brtc exit ; если все нули sbiw r26, 1 ldi r18, 0x3f; то последний не гасить st X, r18 ldi r24, 4
exit: ret Используются соглашение WinAVR, прототип выглядит так: uint8_t BCDto7Segm(uint8_t*, bool); В функцию передаются массив из распакованных двоично-десятичных цифр и признак, означающий, требуется ли гашение. Из функции возвращается позиция последнего погашенного символа - она требуется если число отрицательное, тогда вызываемая программа помещает туда минус.
Сообщение отредактировал IgorKossak - Jul 7 2013, 13:18
|
|
|
|
Сообщений в этой теме
sKWO Гашение незначащих нулей Aug 31 2008, 10:55 alux Цитата(sKWO @ Aug 31 2008, 13:55) Дабы на... Aug 31 2008, 12:39 Павлик я просто сравниваю число , и если оно равняется 0х... Aug 31 2008, 13:26 zltigo Цитата(Павлик @ Aug 31 2008, 15:26) ...ес... Aug 31 2008, 13:45  rezident Цитата(zltigo @ Aug 31 2008, 19:45) Здоро... Aug 31 2008, 15:14   zltigo Цитата(rezident @ Aug 31 2008, 17:14) Как... Aug 31 2008, 15:20 aesok Цитата(sKWO @ Aug 31 2008, 14:55) Какой а... Aug 31 2008, 13:31 Aesthete Animus Ну а кто запрещает пользоваться стандартной snprin... Aug 31 2008, 14:09 aaarrr Цитата(Aesthete Animus @ Aug 31 2008, 18... Aug 31 2008, 14:11 aesok ЦитатаНу и унивесализм, как по радиксу, так и по к... Aug 31 2008, 14:14 _Pasha Цитата(aesok @ Aug 31 2008, 18:14) Обе ис... Aug 31 2008, 15:09 Rst7 Ох, что-то, вы, господа, мрачно тут начали, делени... Aug 31 2008, 15:41 sKWO Цитата(Rst7 @ Aug 31 2008, 19:41) Ох, что... Jul 7 2013, 11:55 Павлик Я тут спорить не собираюсь , сам начинающий и мног... Aug 31 2008, 15:43 zltigo Цитата(Павлик @ Aug 31 2008, 17:43) Предл... Aug 31 2008, 16:22 defunct Код// convert and output decimal value
int IntToSt... Aug 31 2008, 18:00 rx3apf Какие-то все жутковатые алгоритмы... Я вот всю жиз... Jul 7 2013, 12:19 toweroff Цитата(rx3apf @ Jul 7 2013, 16:19) заменя... Jul 7 2013, 13:33 V.K Никогда не думал, что подобные вопросы могут быть ... Jul 7 2013, 13:50 sKWO Цитата(V.K @ Jul 7 2013, 17:50) Никогда н... Jul 7 2013, 14:21 zöner вот тут неплохо разжованы разные алгоритмы преобра... Jul 7 2013, 19:33 Rst7 QUOTE (sKWO @ Jul 7 2013, 14:55) Чисто из... Jul 8 2013, 07:42 sKWO Цитата(Rst7 @ Jul 8 2013, 11:42) Ничего у... Jul 8 2013, 10:03
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|