Чувствую, что напутал что-то с переменными (long и int)

Примитивный скетч отрабатывает для меня неожиданно. Переменная “zzz” объявлена как “long”, однако, при перемножении в ней числа более 181 выходит за пределы, которые характерны для переменной типа “int“ (). То есть, ведет себя не как “long“, а как “int“. Подскажите, где я тут накосячил?

int volt=177; //напряжение (вольты)
int resist=10; //сопротивление (омы)
long zzz=0; //промежуточная переменная
long pwr=0; // мощность (ватты) 

void setup ()
{
  Serial.begin (115200);
}

void loop ()
{
  //Вычисляем мощность (volt*volt/resist)
  zzz=volt*volt;
  pwr=zzz/resist;
  Serial.print (volt);
  Serial.print (" ");
  Serial.print (zzz);
  Serial.print (" ");
  Serial.println (pwr); 
  delay (1000);
  volt++; 
}

Заранее спасибо!

В ней ничего не перемножается. Перемножаются два числа int, вот тут и происходит переполнение

Простите, а что Вы понимаете под выражением

?

Я не знаю, что эти слова означают, но в Вашем коде явно написано что-то другое:

Здесь. Присутствуют два операции. Приоритет операции умножения выше приоритета операции присваивания. Поэтому, сначала выполняется умножение двух величин типа int (результат имеет тип int), а потом этот результат присваивается переменной типа long.

Так что, всё работает как написано.

Написал непонятно, признаю. Но как поступить? Объявить volt тоже как long? Жалко память тратить.

Можно, например, так

zzz = volt;
zzz *= volt / resist;

Подумать. Тут миллион вариантов и большинство из них просты как валенок и не требуют

:slight_smile: на миллион вариантов мне знаний не хватает.

Если жалко, то можно вообще volt и resist объявить как int8_t. Если там больше 255 не будет ))

Тааак… Будем пробовать. Уже два варианта :slight_smile:

Да, нет, что Вы. Приоритет деления сильно выше, чем приоритет *= Вы сначала поделите, а потом умножать будете

Ну да. А у него сначала умножается, а потом все равно делится. Итог будет один ))

Можно и так

zzz = (long)volt * volt;

pwr = long(volt) * volt / resist;

Нет. Это же целочисленное деление.

Смотрите:


(25 * 25) / 30 = 20 (при целочисленном делении остатки отбрасываются)
но при этом
25 * (25 / 30) = 0 (по той же причине)

Ну да, тут мой недогляд ))

Мне остаток деления в данном случае пофиг. Попробую.

Прокатывает!!! Спасибо!!! Принцип понял. Пойду ваять дальше.

@Sonologist А потом ещё пару тем с тем же вопросом :grinning_face:, может почитать чего!?
Хоть у Gyver, заодно и про ul, L, u узнаете.

Спасибо за ссылки! Обязательно!

На данный момент проверил работу во всех диапазонах - всё штатно, пока вопрос снят. Вернее - решен.

Деда, а почему именно так?
То есть в выражении где один член имеет явное приведение типа, то считается что и все члены тоже будут приведены к этому типу? Так?