Преобразование BIN -->BCD

Сынулька в подобных ситуациях всегда подкалывает меня цитатой из этого ролика.

1 лайк

да я это видел, 512, 1024 и 2048

Всё, выходи. И да начнется жатва…

Наданапицца.

А я подумал, что ты “уже” ))

Пока нет, у мня еще сонца не село

@dedivan,

как я Вам уже говорил, мне надоела Ваша клоунада про ассемблер, но Вы проигнорировали мою просьбу прекратить. Давайте поступим так, я предлагаю Вам

Джентльменское пари

Присутствующие коллеги будут судьями.

Суть пари: Вы пишете функцию для вычисления чисел Фибоначчи на ассемблере (вставкой в С++ или отдельным файлом, как Вам удобнее), А я пишу функцию для того же на С++. Затем мы запускаем вот такой

тест
//
// Здесь функция Fib, считающая числа Фибоначчи
//    Fib(0) = 0
//    Fib(1) = 1
//    Fib(n) = Fib(n-1) + Fib(n-2) (при 1 < n < 25)
//    Fib(n) = 0xFFFF (при n > 24)
//
// .......

void setup(void) {
	Serial.begin(9600);
   const uint32_t start = micros();
   const uint16_t result = Fib(24);
   const uint32_t duration = micros() - start;
   Serial.print("F(24)=");
   Serial.println(result);
   Serial.print("Время: ");
   Serial.print(duration);
   Serial.println(" us");
}

void loop(void) {}

И сравниваем размер памяти (программы и данных) и быстродействие (время расчёта). Если показатели моей функции лучше (по мнению судей), то Вы затыкаетесь и больше ни слова про преимущества ассемблера здесь не вещаете. Если же проиграю я, то я затыкаюсь и больше никак не критикую и не обсуждаю Ваши перлы про ассемблер.

Формальные условия:

  1. Тестовая программа как приведена – только добавить функцию вычисления чисел Фибоначчи;
  2. MCU – ATmega328P;
  3. среда компиляции скетча – Arduino IDE 2.2.1 с опциями «из коробки», т.е. чистая установка безо всяких подкручиваний;
  4. Каждый участник выкладывает свой скетч в полном виде, чтобы любой желающий мог запустить его у себя и сверить результаты.
  5. Время на написание функции назначьте сами. Я готов написать нс С++ на пару минут.

Формальное определение требуемой функции:

  1. Тип возвращаемого значения – uint16_t
  2. Один параметр типа uint8_t может принимать значения от 0 до 24 включительно (при большем параметре результат не влезет в uint16_t)
  3. Функция должна возвращать:
    Fib(0) = 0
    Fib(1) = 1
    Fib(n) = Fib(n-1) + Fib(n-2); (при 1 < n < 25)
    Fib(n) = 0xFFFF; (при n > 24) – это будет признаком ошибки в параметре

Кстати, результат приведённого выше теста – 46368 (это легко проверить вручную)

кстати

Обратите внимание, я специально выбрал задачу в которой используются только операции целочисленного сложения, чтобы не устраивать для Вас весёлую жизнь с умножениями плавающих чисел, как тут предлагали - цените.

Ну, как, согласны на деле продемонстрировать преимущества ассемблера? Или только языком можете?

3 лайка

А можно на чём то типа 1.18… портативном ? Не хочу пачкать комп … 2… версиями. (или в wokwi.com)

1 лайк

У меня вот так получилось )))

Спойлер
//
// Здесь функция Fib, считающая числа Фибоначчи
//    Fib(0) = 0
//    Fib(1) = 1
//    Fib(n) = Fib(n-1) + Fib(n-2) (при 1 < n < 25)
//    Fib(n) = 0xFFFF (при n > 24)
//
// .......

uint16_t Fib (uint8_t num);

void setup(void) {
	Serial.begin(9600);
   const uint32_t start = micros();
   const uint16_t result = Fib(20);
   const uint32_t duration = micros() - start;
   Serial.print("F(24)=");
   Serial.println(result);
   Serial.print("Время: ");
   Serial.print(duration);
   Serial.println(" us");
}

void loop(void) {

}

uint16_t Fib (uint8_t num) {
  
  if (num == 0) return 0;
  if (num == 1) return 1;
  if (num > 24) return 0xFFFF;
  
  return Fib (num - 1) + Fib (num - 2);
}

Результаты в Wokwi:
//===================
F(24)=46368

Время: 187288 us
//===================
F(15)=610

Время: 2464 us

А память?

У меня в Wokwi время всегда 0 … видимо я что то делаю не так … :cry:

F(24)=46368
Время: 0 us

F(15)=610
Время: 0 us

uint16_t Fib (uint8_t num) {
    const uint16_t f[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368};
    return num > 24 ? 0xffff : f[num];
}

void setup(void) {
    Serial.begin(9600);
    const uint32_t start = micros();
    const uint16_t result = Fib(24);
    const uint32_t duration = micros() - start;
    Serial.print("F(24)=");
    Serial.println(result);
    Serial.print("Время: ");
    Serial.print(duration);
    Serial.println(" us");
}

void loop(void) {}

1.18.19

скетч @BOOM
Скетч использует 1924 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 212 байт (10%) динамической памяти, оставляя 1836 байт для локальных переменных. Максимум: 2048 байт.

скетч @Komandir
Скетч использует 1862 байт (6%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 212 байт (10%) динамической памяти, оставляя 1836 байт для локальных переменных. Максимум: 2048 байт.

1 лайк

Давайте уже ваш вариант - запущу у себя и опубликую результат для статистики ?

При настолько ограниченном значении входного параметра - это слишком неудачная функция.

Вам шашечки или ехать ???

1 лайк

Но не для всемогущего ассемблера ведь? ))

Сдаётся мне, что всё это на этапе оптимизации схлопывается до:

void setup(void) {
    Serial.begin(9600);
//    const uint32_t start = micros();
//    const uint16_t result = Fib(24);
//    const uint32_t duration = micros() - start;  //  => micros() - micros();
    Serial.print("F(24)=");
    Serial.println(46368);
    Serial.print("Время: ");
    Serial.print(0);
    Serial.println(" us");
}

У меня то не “схлопывается”.

Про успехи компилятора в условиях не было ничего !!!

Пусть @ЕвгенийП изменит основную часть и сделает прогон от 0 до 25 с расчётом общего времени, тогда уже компилятору буде сложнее что то отбросить …

так, а чего Вы ожидали с такой программой? micros() меняется через 4 мкс (это её шаг), а вот эта Ваша функция работает явно меньше 4 мкс. Всё у Вас правильно, правда константы я не проверял.