0

I was creating a scoring formula for a game.

The formula in question is

millis() * 1.1 ^ (millis()/10000);

However, I'm having trouble understanding the different error messages that the Arduino IDE is projecting to me

invalid operands of type to binary operator

I have declared the score as an unsigned long.

Greenonline
3,1527 gold badges36 silver badges48 bronze badges
asked Sep 28, 2018 at 10:51
4
  • ^ is the binary exclusive-or operation. You are probably trying to raise it to the power of. Use pow(base, exponent) instead. Commented Sep 28, 2018 at 10:54
  • Creating two declarations, score = millis() * 1.1 and divisor = millis()/10000 and then creating a new unsigned long machinescore = pow(score, divisor) outputs consistent 1's. does it have anything to do with it being integer math? as such it wont display anything until something is greater than another? Commented Sep 28, 2018 at 11:03
  • add a .0 for the divisor: 'millis()/10000.0'. Hopefully you've also declared both score and divisor as floating point numbers. Also the result will be a floating point number. This is basic C programming language stuff. You can try it on your local machine instead of uploading it to the board every time you try to figure out something. Commented Sep 28, 2018 at 11:09
  • Thank you so much, ive been working on other projects hence the arduino IDE. cant wrap my head around basic principals at the moment. Commented Sep 28, 2018 at 11:15

1 Answer 1

4

I would avoid calling millis() twice within the same expression. Not really a big deal in your case, but the two calls can very well return different values, which would make your formula slightly inconsistent. Then, using the proper syntax for the power function, as explained by Kwasmich:

uint32_t t = millis();
float score = t * pow(1.1, t/1e4);

Note that 1e4 is the scientific notation for 10000.0. I personally find the former more readable, as you don't have to count the zeros.

Now, it is worth noting that the pow() function is very expensive to compute on this kind of 8-bit FPU-less processor. It involves both a logarithm and an exponential. The second line is essentially equivalent to

float score = t * exp(t/1e4 * log(1.1));

The floating point division is also quite expensive. You could save something like half the processing cycles by pre-computing log(1.1)/1e4 and using the result in your expression:

float score = t * exp(t * 9.53e-6);
answered Sep 28, 2018 at 11:55
2
  • Thanks for that, i added it in and it works as the graph shows. I do have another question if you could help. I'm preparing the score to send via UART so i need to convert the score in 4 8bit packets, my way of thinking is using modulus 256 and storing the frames in a respective variable to send, but i can only think of how to do it once, leaving me with 24 more bits to shift and send. cheers for any help. Commented Sep 29, 2018 at 4:09
  • 1
    @ReidPilkington: To send numeric data through the serial port, use Serial.println(score). This will format the number in ASCII. If that can't work for you, open another question, explain why ASCII won't do it, and provide a complete specification of the binary format you want (IEEE 754 v.s. integer, endianness...). Commented Sep 29, 2018 at 9:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.