Странные результаты при работе с разными типами данных

DisSevsk

✩✩✩✩✩✩✩
25 Дек 2019
3
0
Всем привет, начал осваивать работу с платформой ардуино и столкнулся с интересным эффектом при математических операциях с разными типами данных, решения проблемы в статьях Гайвера не нешел (или смотрел плохо). Суть:
есть цикл

uint32_t r;
for (byte z = 1; z <= 255; z++){
r = z*1000;
}

на счетчике z=33 r становится равным 4294934760 (результаты вывожу через Serial)
на z=66 r=464
пробовал на разных ардуинках - результат тот же

работает корректно
for (byte z = 1; z <= 255; z++){
r = z*100;
r= r*10
}

при замене типа данных счетчика с byte на uint16_t
for (uint16_t z = 1; z <= 255; z++){
r = z*1000;
}
при счечике z=66 r=464

все корректно работает только при замене счетчика на uint32_t
for (uint32_t z = 1; z <= 255; z++){
r = z*1000;
}
но зачем мне менять тип с 1байта на 4, если мне в цикле нужно сделать всего 255 итераций
Так же интересна ситуация с возведением в степень:
uint32_t r;
r = pow(10,3); все корректно = 1000
byte z=3;
r = pow(10,z); = 999?
byte z=8;
r = pow(10,z); = 99999968?
r = pow(10,8); = 100000000

Буду благодарен, если обьясните почему это происходит и как с этим бороться
 

Старик Похабыч

★★★★★★✩
14 Авг 2019
2,336
637
Москва
замени uint32_t на uint64_t и 1-ый цикл будет работать.
Ничего странного нет. есть такое понятие : тип данных. под определенный тип данных отводится определенные количество бит информации
вот тип данных uint32_t будет использовать 32 бита данных и не будет использовать отрицательные числа. Это значит, что максимально допустимое число будет от 0 до 2 в степени 32 и от результата отнять 1, т.е. 0-4294967295
Для uibt64_t будет 64 бите будет от 0 до 2 в степени 64 , потом -1 , т.е. 0 - 18446744073709551615
ну и байт использут 8 бит, от 0 до 255. если же взять int8_t, то это будет 7 бит числа и 1 бит знака (u нет) т.е. от -128 до 127 (кажется не напутал тут)

дальше надо бы так:

uint64_t r;
for (byte z = 1; z <= 255; z++){
r = z*1000;
}

а если надо умножить байт на байт и получить другое число используют приведение типов. типа так
byte a,b;
uint16_t c
a=255;b=255;
c=(uint16_t )a*b;