Чувствую, что напутал что-то с переменными (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, вот тут и происходит переполнение

2 лайка

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

?

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

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

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

1 лайк

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

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

zzz = volt;
zzz *= volt / resist;

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

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

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

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

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

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

Можно и так

zzz = (long)volt * volt;
2 лайка

pwr = long(volt) * volt / resist;

4 лайка

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

Смотрите:


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

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

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

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

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

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

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

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