modulo not working as expected

Hey Guys,

i'm using a construction like this:

#define SOMETHING 4
uint8 g_a_variable = 0;

...


g_a_variable = (g_a_variable - 1) % SOMETHING;

Why goes g_a_variable to 255 instead of 3, as expected? Can someone please tell me what's wrong?

Thanks a lot

Lena

What value has an UNSIGNED int_8 = 0 -1?

Yes, but why has the modulo 4 no effect? Same construct with increment works fine and counts from 0 to 3 round and round.

Lena: uint8 g_a_variable = 0;

What's the "uint8"?

255 % 4 = -1 ???

shure?

255 / 4 = 63 remainder 3

so i expect 255 % 3 = 3

Is this wrong?

user091ard: What's the "uint8"?

to be exact: uint8_t = unsigned int 8 bit

uint8_t var = 0;

void setup() {
  Serial.begin(250000);
  Serial.print(F("var\t\t"));
  Serial.println(var);
  Serial.print(F("--var\t\t"));
  Serial.println(--var);
  Serial.print(F("var%4\t\t"));
  Serial.println(var % 4);
  Serial.print(F("(byte)(0-1)%4\t"));
  Serial.println((byte)(0 - 1) % 4);
  Serial.print(F("((byte)0-1)%4\t"));
  Serial.println(((byte)0 - 1) % 4);
}
void loop() {}
var     0
--var       255
var%4       3
(byte)(0-1)%4   3
((byte)0-1)%4   -1

Expressions with bytes or chars are promoted to integer. The last line shows that behaviour. If you want to have it interpreted differently, cast the expression.

That seems to happen. uint8_t is internal converted to int resulting -1. -1 % 4 = -1 -1 assigned to uint8_t results to 255. What do you mean by cast the expression?

This is the answer. :)

g_a_variable = (g_a_variable - 1) % 4; ^^^^^^^^^^^^^^^^ | g_a_variable is promoted to int, so the result of that part is 0 - 1 => -1.

g_a_variable = -1 % 4; ^^^^^^ | this is -1 (look at the link)

And finally: g_a_variable = 255 (-1 => 255)

I didn't realize this. Great question! :)

Lena: What do you mean by cast the expression?

(byte)(0-1) % 4 == 3

Ah, ok, explicit tell the datatype of the “subexpression” g_a_variable - 1

so

g_a_variable = uint8_t(g_a_variable - 1) % 4;

should do the trick?
I’ll check it out -one moment please…
Works perfectly!
Thanks a lot - learned a bit about internal conversion and casting.

P.S.: why are you using c notation in a c++ environment? Fashion?

I would useg_a_variable = --g_a_variable % 4; I use the C-notation for casts because I learned it long before C++ existed.

I wonder, it works too. For me there was no difference between --var and var - 1 but now i see --var has no internal conversion. Little problem but learned a lot - thank you very much! Is it because the compiler interprets the "1" as integer?

Lena: Is it because the compiler interprets the "1" as integer?

Is it because the compiler treats any expression (a+b, a-b, ...) as integer if not advised otherwise, which could be casts or implicit via variable/constant types (if not byte or int types).

Whandall: Is it because the compiler treats any expression (a+b, a-b, ...) as integer if not advised otherwise, which could be casts or implicit via variable/constant types (if not byte or int types).

As signed integer? That is really important to know. I think i have had a lot of luck so far. I thank you very much! Now i have to quit - must get up a quarter to 5am :(