-1

The first time, pow() works. But inside of a 'for loop', or again afterwards, it doesn't behave !? (I'm using a Chinese Pro Mini with Arduino 1.8.16)

EDIT To clarify what I am asking, my question is: "Why does pow() only give the correct answer the first time?"

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){}
}

Here's what the serial monitor shows:

100000

HERE'S THE SAME CODE INSIDE OF A 'FOR LOOP'

99999

99999

99999

99999

99999

NOW THE EXACT SAME CODE AS BEFORE GIVES A DIFFERENT RESULT

99999

0

1 Answer 1

3

This seems like a case of a confused compiler. More specifically, a confused optimizer.

On the first occurrence of pow(10, places), the compiler noticed that places must be equal to 5, and so replaced the expression with its value. If you disassemble the compiled code, you will notice it calls

Serial.println(100000);

On the following occurrences, the compiler did not notice that places can not be anything other than 5, so it did not optimize-out the call to pow(), and got the result 99999.9765625. This is 3 ULPs less than the exact result, and is consistent with the accuracy you can expect from pow(). Converting to an integer implicitly rounds towards zero, hence the printed result: 99999.

3
  • What is ULPs? My search came back with Ultra Low Power, but that's probably not what you were talking about. I don't understand where the error is coming from, nothing really changed, and the calculation is seemingly very simple. What can I do to make my sketch run properly? Did I ask a low quality question? I put a good deal of effort into it and felt that the result was to the best of my ability. Perhaps this isn't the place for someone with my skills to be posting. I feel like I have made a nuisance of myself and do not wish to do so again, Your candid thoughts would be appreciated.
    – TRS-80
    Nov 13, 2021 at 20:14
  • @TRS-80: ULP = Unit in the last place. To get the correct result, write (or search for) an integer power function, or use round(pow(...)). Nov 13, 2021 at 21:16
  • Great! That fixed my problem, thanks very much! You were extremely helpful with the programming aspect, I guess I must have been violating boundaries by asking for etiquette advice. Sorry.
    – TRS-80
    Nov 13, 2021 at 21:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.