Умножить char на float
У меня есть значение яркости светодиода, которое хранится в виде unsigned char
(0-255)
unsigned char* colors[3];
colors[0] = 255;
colors[1] = 0;
colors[2] = 0;
Я хочу умножить процент яркости на это значение.
float percent = 0.5;
auto red_brightness = colors[0] * percent
Поскольку colors[0]
имеет тип char
, а percent
имеет тип float
. Выдает ошибку Недопустимые операнды типов 'unsigned char*' и 'float' для двоичного 'operator*'
unsigned char brightness;
float percent;
unsigned char* colors[3];
void setup() {
Serial.begin(9600);
colors[0] = 255;
colors[1] = 0;
colors[2] = 0;
}
void loop() {
brightness = 127;
float percent = (float)brightness / 255;
float newRed = (float)colors[0] * percent;
Serial.println(percent);
Serial.print("red ");
Serial.print(newRed);
Serial.println("");
delay(1000);
}
Как умножить colors[0]
(255) на 0,5
, чтобы получить 127
?
Что я пробовал
- Приведение
colors[0]
к типу float или int
# invalid cast from type 'unsigned char' to type 'float'
float newRed = (float)colors[0] * percent;
- строд
С помощью этого веб-сайта для конвертации я попытался преобразовать, например, так:
float tempColor = (float)strtod(colors[0],NULL);
float newRed = tempColor * percent;
При компиляции он всегда возвращает 0
(а не 127
, как я ожидаю)
unsigned char brightness;
float percent;
unsigned char* colors[3];
void setup() {
Serial.begin(9600);
colors[0] = 255;
}
void loop() {
brightness = 127;
float percent = (float)brightness / 255;
float tempColor = (float)strtod(colors[0],NULL); // <- returns 0.00
Serial.print("tempColor");
Serial.println(tempColor);
delay(1000);
}
Как мне умножить 255
на 0,5
, чтобы получить ~127
?
Решение
Благодаря указателю от st2000 и этой статье о типах данных
Я избегал массивов с плавающей запятой и символов и преобразовал все в byte
, и теперь мой код работает так, как ожидалось. Спасибо
byte brightness;
byte percent;
byte colors[3];
void setup() {
Serial.begin(9600);
colors[0] = 255;
}
void loop() {
percent = 50;
auto foobar = colors[0] * percent / 100;
Serial.print("foobar: ");
Serial.println(foobar);
11:12:19.833 -> foobar: 127
@spuder, 👍0
2 ответа
Лучший ответ:
Использование "плавающих чисел" стоит дорого как в требуемом пространстве, так и во времени выполнения. Попробуйте полностью избежать этой проблемы и используйте uint8_t или byte для всего.
Тогда просто предположим
percent = 50;
... составляет 50%. Тогда попробуйте:
tempColor = colors[0] * percent / 100;
... где все переменные имеют тип uint8_t или byte.
Вы писали:
У меня есть яркость светодиода, которая хранится в виде
unsigned char
(0-255)unsigned char* colors[3];
Это не массив unsigned char
, это массив
указатели на unsigned char
. Если вы вместо этого напишете
unsigned char colors[3];
Все должно работать как положено.
Но в то же время у st2000 есть очень хороший совет, как избежать дорогостоящих операций с плавающей запятой. точечные операции.
Оооо, хороший улов @edgar!, @st2000
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
- Является ли использование malloc() и free() действительно плохой идеей для Arduino?
- Можно ли сделать несколько функций loop() с помощью Arduino Uno?
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- устаревшее преобразование из строковой константы в 'char*'
@spuder, пожалуйста, сообщите нам, работает ли приведенное выше предложение по коду. Я думаю, что C использует тип int для промежуточных значений, и в этом случае наихудший ожидаемый случай (255 * 100) не должен превышать пределы переменной типа int. В противном случае приведение одной из переменных к типу uint16_t, скорее всего, сделает код более переносимым/ менее вероятным., @st2000