Создание формулы

Я создавал формулу подсчета очков для игры.

Рассматриваемая формула

millis() * 1.1 ^ (millis()/10000);

Однако у меня возникли проблемы с пониманием различных сообщений об ошибках, которые мне проецирует Arduino IDE

недопустимые операнды типа бинарного оператора

Я объявил счет как беззнаковый длинный.

, 👍0

Обсуждение

^ — это двоичная операция «исключающее ИЛИ». Вы, вероятно, пытаетесь возвести это в степень. Вместо этого используйте pow(база, экспонента)., @Kwasmich

Создание двух объявлений,core = millis() * 1.1 и divisor = millis()/10000, а затем создание нового беззнакового длинного объявления Machinecore = pow(score, divisor) выводит последовательные 1. это имеет какое-то отношение к целочисленной математике? как таковой он ничего не будет отображать, пока что-то не станет больше другого?, @Reid Pilkington

добавьте .0 для делителя: 'millis()/10000.0'. Надеюсь, вы также объявили и счет, и делитель как числа с плавающей запятой. Также результатом будет число с плавающей запятой. Это базовые вещи на языке программирования C. Вы можете попробовать это на своем локальном компьютере вместо того, чтобы загружать его на доску каждый раз, когда пытаетесь что-то выяснить., @Kwasmich

Большое вам спасибо, я работал над другими проектами, отсюда и Arduino IDE. На данный момент не могу уложить в голове основные принципы., @Reid Pilkington


1 ответ


4

Я бы не стал дважды вызывать millis() в одном и том же выражении. Нет в вашем случае это действительно имеет большое значение, но два вызова вполне могут вернуться разные значения, что сделает вашу формулу немного противоречивой. Затем, используя правильный синтаксис для степенной функции, как объяснено Квасмич:

uint32_t t = millis();
float score = t * pow(1.1, t/1e4);

Обратите внимание, что 1e4 — это экспоненциальное обозначение 10000.0. Я лично найдите первое более читабельным, так как вам не нужно считать нули.

Стоит отметить, что функция pow() требует очень больших затрат. выполнять вычисления на таком 8-битном процессоре без FPU. Оно включает в себя как логарифм и экспонента. Вторая строка по сути эквивалентна чтобы

float score = t * exp(t/1e4 * log(1.1));

Деление с плавающей запятой также довольно дорого. Вы могли бы сэкономить что-то вроде половины циклов обработки за счет предварительных вычислений log(1.1)/1e4 и используйте результат в своем выражении:

float score = t * exp(t * 9.53e-6);
,

Спасибо за это, я добавил его, и он работает, как показано на графике. У меня есть еще один вопрос, если вы можете помочь. Я готовлю партитуру для отправки через UART, поэтому мне нужно преобразовать партитуру в 4 8-битных пакета. Я думаю, что использую модуль 256 и сохраняю кадры в соответствующей переменной для отправки, но я могу только думать о том, как это сделать. это один раз, и мне осталось сдвинуть и отправить еще 24 бита. приветствую любую помощь., @Reid Pilkington

@ReidPilkington: Чтобы отправить числовые данные через последовательный порт, используйте Serial.println(score). Это отформатирует число в ASCII. Если это не сработает для вас, откройте _другой_ вопрос, объясните _почему_ ASCII не будет этого делать и предоставьте _полную спецификацию_ желаемого двоичного формата (IEEE 754 против целого числа, порядок байтов...)., @Edgar Bonet