Т.е. каждый раз сравнивают (проверяют), что разность больше чем вычитаемое, тогда продолжают вычитать. Накапливают переменную. и так далее с каждым разрядом?
Понимаю, что надо использовать деление на 10 и остаток от деления на 10. Много чего уже посмотрел, но все равно плохо доходит.
Так ведь Eddy_Em в Сообщении от Вт ноя 22, 2022 11:07:19 на предыдущей странице уже всё расписал!
Цитата:
Суть в том, что я не знаю, сколько разрядов у числа изначально. Может быть три, а может пять.
А какая разница, сколько их? Изначально буфер на 5 символов надо заполнить пробелами или каким другим пустым кодом, если кодировка не ASCII. Цифры же формируются с конца (обратите внимание на --bufptr у Eddy_Em), и этот цикл заканчивается не по счётчику, а по нулевому остатку от исходного числа. При этом сколько символов сформировалось, столько и ладно. Программа даже не заморачивается подсчётом этих символов!
Цитата:
Опишите суть, или ткните, где это максимально понятно расписано.
AVR Application Note 204: BCD Arithmetics. Начинается этот аппноут как раз с программы, а точнее с алгоритма Binary 16 to BCD Conversion. А хорошее разъяснение всей этой математики есть в 3-м томе 4-томника "Микроконтроллеры" от Алекса Фрунзе. Не столь популярное, но тоже небесполезное описание всё той же самой математики есть и в жёлтой книжке "Программы для микропроцессоров" Гуртовцева и Гудыменко. И всё это есть в сети.
Т.е. каждый раз сравнивают (проверяют), что разность больше чем вычитаемое, тогда продолжают вычитать. Накапливают переменную. и так далее с каждым разрядом?
да, каждый раз нужно сначала делать проверку на возможность вычесть, потом вычитают. а иногда делают наоборот - сначала вычитают, потом проверяют остаток на знак. если положительный, продолжают вычитать. если отрицательный, прибавляют и переходят к следующему разряду.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
veso74, что-то мне не верится, что деление и потом взятие %10 работает быстрее вычитания. я не умею писать для МК на Си, чтобы самому это проверить.
Поверьте, быстрее. Компиляторы сейчас умные, и при включенной (по умолчанию) оптимизации сами реализуют деление на 10 как умножение со сдвигом, что и кода меньше занимает, и по времени гораздо быстрее, чем отнимать и считать циклы.
К примеру, вместо целочисленного деления uint8_t числа на 10 компилятор сам может сообразить, что это то же самое, что умножить это число на 205 и результат сдвинуть на 11 разрядов вправо.
Почему 205? Потому что X / 10 = X * 204.8 / 2048 ~= X * 205 / 2048 = (X * 205) << 11. Что для любых чисел само по себе приблизительно, но для однобайтовых X погрешность нулевая.
+1000500. Считаю, и не только я, что в наше время, в первую очередь, нужно обращать внимание на наглядность исходного текста, а не заниматься "оптимизацией". Все эти оптимизации ушли вместе с ассемблером.
WiseLord, а если число большое и нужно поделить на 10 тысяч или на 10 миллионов?
Принцип остаётся тот же - заменить деление на умножение и сдвиг. Если контроллер умеет аппаратно умножить два 8бит числа с 16бит результатом, то и умножение чисел с большей разрядностью легко сводится к умножению октет и суммироованию, что всё равно обходится дешевле циклов вычитаний.
Добавлю: встроенная функция avr-gcc позволяет иметь остаток от деления одновременно с получением частного. Т.е. не сначала деление, а потом взятие остатка от деления, а за один вызов. Думаю, оптимизатор распознает эту ситуацию и делает с минимальными затратами.
Если честно, то вообще не понимаю, к чему в данной ситуации погоня за тактами... Индикация - процесс настолько низкоприоритетный и медленный, что экономить на нем просто глупо...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
mont-oriol, да, компилятор считает один раз. С расчетом в цикле изменилось: 24 µs к 72 µs. Нравится, есть где использовать.
А лично в 99% случаев неважно как написано - от этого ничего не зависит (скорость?), и если память будет на пределе (если, конечно не любимый ATtiny13A). Вопрос ради вопроса.
ARV И если критична производительность и/или объем кода - то стоит задуматься, а нужен ли тут float ?
Вспомнила, делался какой то показометр на линейке диодов, там логарифмическое что то просили считать. Пришлось туда втулить.
А если некритичны производительность и/или объем кода – то тоже стоит задуматься, а нужен ли тут float?
Как я понял из последней фразы, из-за логарифма вы «втулили» float. Так в целочисленной арифметике тоже есть логарифм. Например, в, условно говоря, хорошем ассемблере есть вызов функции логарифма. Одна строчка - и есть готовый логарифм. По объёму и скорости выполнения программа наверняка будет лучше. Скорее всего, подойдёт самый простой вариант, где аргумент – 2 байта. У него точность вроде как полпроцента, вполне достаточно для рядовых целей. Диапазон, правда, небольшой, но, скорее всего, несложно расширить с помощью простой школьной арифметики.
AQ29, Вам шашечки или ехать? Суть была в чем - пихать флоаты налево и направо - не стоит. В большинстве (обратите внимание - не всегда) случаев от флоатов можно отказаться. Но иногда с ними проще. У меня проектов на мелких МК с флоатами - ну вот только один и вспомнился. В остальных случаях получилось уйти к целочисленной математике. Ну там, где вообще надо было к ней уходить. Касательно флоата и логарифма. Это заказной проект был. Не особо дорогой. И тратить свое время на какие то изыски - не выгодно было. Я отдавала себе отчет, что флоаты на авр - не самое лучшее решение... Но в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм? Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ? Куда мне девать эти такты и килобайты? Солить на зиму? Поэтому проще и быстрее взять флоатный логарифм (заодно не трахаться с пересчетом дробных коэффициентов, участвующих в расчетах, в целочисленные) и получить на выходе нужное мне число. Которое потом округлится в целочисленную переменную и засветится на шкале. Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались... Всё остальное процессорное время - в моем распоряжении..... И его для той задачи - много. Там можно считать что угодно, хоть float-ом, хоть double-ом... Подождать флаг прихода данных или обновления АЦП -пересчитать данные и обновить инфу для диодов.. Программа в восьмую мегу поместилась, около 30% флеша свободно осталось, в ТЗ по таймингам - умещалось с запасом. А, и еще не надо спорить с заказчиком. Им надо было, что б все было точно-точно... Дали ТЗ с формулами - получили результат. Я получила денешшшшку. И все довольны. Зачем мне тратить свое время в таком случае на придумывание?...
в данном случае ресурсов хватало и таймингов тоже. Зачем мне искать/придумывать ассемблерный вариант или целочисленный алгоритм? Что бы процессор в idle крутился не 40, а 60% времени? Или что бы свободного флеша у меня оставалось не 30, а 50% ? Куда мне девать эти такты и килобайты? Солить на зиму?
Вот, кстати, согласен на все 146%.
Цитата:
Управление двумя линейками диодов было сделано из таймерного прерывания, чтение полученных извне данных - там же. Заодно в том же таймерном прерывании еще и АЦП опрашивался и перезапускался. И его данные в массив для усреднения складывались...
Аналогичную задачу я решал (и решил) на 13-й тиньке, но (оффтопик!) на ассемблере, поскольку из прикидок на ардуине мне показалось, что на С, да ещё с логарифмом в плавающей запятой я в мелкую тиньку не уложусь: размер кода для 48-й атмеги даже без плавающей запятой был 1864 байта. На асме, конечно, уложился. Объём прошивки стал 760 байт, быстродействие упёрлось в АЦП, а не в процессор, и возник тот же самый вопрос: куда девать лишние такты и лишние байты (25% памяти)???
Цитата:
Зачем мне тратить свое время в таком случае на придумывание?...
Абсолютно справедливая постановка вопроса, ибо никогда не надо забывать про критерий разумной достаточности.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения