Умножить 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?


Что я пробовал

  1. Приведение colors[0] к типу float или int
    # invalid cast from type 'unsigned char' to type 'float'

    float newRed = (float)colors[0] * percent;
  1. строд

С помощью этого веб-сайта для конвертации я попытался преобразовать, например, так:

    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

, 👍0


2 ответа


Лучший ответ:

1

Использование "плавающих чисел" стоит дорого как в требуемом пространстве, так и во времени выполнения. Попробуйте полностью избежать этой проблемы и используйте uint8_t или byte для всего.

Тогда просто предположим

percent = 50; 

... составляет 50%. Тогда попробуйте:

tempColor =  colors[0] * percent / 100;

... где все переменные имеют тип uint8_t или byte.

,

@spuder, пожалуйста, сообщите нам, работает ли приведенное выше предложение по коду. Я думаю, что C использует тип int для промежуточных значений, и в этом случае наихудший ожидаемый случай (255 * 100) не должен превышать пределы переменной типа int. В противном случае приведение одной из переменных к типу uint16_t, скорее всего, сделает код более переносимым/ менее вероятным., @st2000


4

Вы писали:

У меня есть яркость светодиода, которая хранится в виде unsigned char (0-255)

unsigned char* colors[3];

Это не массив unsigned char, это массив указатели на unsigned char. Если вы вместо этого напишете

unsigned char colors[3];

Все должно работать как положено.

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

,

Оооо, хороший улов @edgar!, @st2000