Для loop, похоже, изменяется выполнение pow()

В первый раз pow() работает. Но внутри "цикла для" или снова после этого он не ведет себя !? (Я использую китайский Pro Mini с Arduino 1.8.16)

Обновление Чтобы прояснить, о чем я спрашиваю, мой вопрос таков: "Почему pow() дает правильный ответ только в первый раз?"

uint8_t places;
uint8_t temp8;
uint32_t n;

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

void loop() {
  places  = 5U;

  n = pow( 10, places);
  Serial.println(n);

  Serial.println("\nHERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'\n");

  for (temp8 = 0; temp8 < places; temp8++)  {
    n = pow( 10, places);
    Serial.println(n);
  }

  Serial.println("\nNOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT\n");

  n = pow( 10, places);
  Serial.println(n);
 
  while(1){}
}

Вот что показывает последовательный монитор:

100000

ВОТ ТОТ ЖЕ КОД ВНУТРИ ЦИКЛА "ДЛЯ"

99999

99999

99999

99999

99999

ТЕПЕРЬ ТОТ ЖЕ САМЫЙ КОД, ЧТО И РАНЬШЕ, ДАЕТ ДРУГОЙ РЕЗУЛЬТАТ

99999

, 👍-1


1 ответ


3

Это похоже на случай запутанного компилятора. Точнее, сбитый с толку оптимизатор.

При первом вхождении pow(10, места)компилятор заметил, что места должны быть равны 5, и поэтому заменил выражение его значением. Если вы разберете скомпилированный код, вы заметите, что он вызывает

Serial.println(100000);

В следующих случаях компилятор не заметил, что мест не может быть больше 5, поэтому он не оптимизировал вызов pow ()и получил результат 99999.9765625. Это на 3 ульпа меньше, чем точный результат, и соответствует точности, которую вы можете ожидать от pow(). Преобразование в целое число неявно округляется до нуля, следовательно, выводится результат: 99999.

,

Что такое ULPs? Мой поиск вернулся со сверхнизкой мощностью, но, вероятно, это не то, о чем вы говорили. Я не понимаю, откуда берется ошибка, на самом деле ничего не изменилось, и расчет, казалось бы, очень прост. Что я могу сделать, чтобы мой скетч работал правильно? Я задал вопрос низкого качества? Я приложил к этому немало усилий и чувствовал, что результат был в меру моих возможностей. Возможно, это не то место, где должен публиковаться человек с моими навыками. Я чувствую, что навлек на себя неприятности и не хочу делать этого снова, Ваши откровенные мысли будут оценены по достоинству., @TRS-80

@TRS-80: ULP = [Единица измерения на последнем месте](https://en.wikipedia.org/wiki/Unit_in_the_last_place). Чтобы получить правильный результат, напишите (или найдите) целочисленную степенную функцию или используйте " round(pow(...))`., @Edgar Bonet

Отлично! Это решило мою проблему, большое спасибо! Вы были чрезвычайно полезны в аспекте программирования, я думаю, я, должно быть, нарушил границы, попросив совета по этикету. Извините., @TRS-80