You are likely wondering what are uint8_t, uint16_t, uint32_t and uint64_t.
That's a good question. Because it could be really helpul!
It turns out that they are equal respectively to: unsigned char, unsigned short, unsigned int and unsigned long long.
But what are ranges of all these types?
Let's test it in this C type tutorial.
We're going to use a variable called testValue equal to 0xFFFFFFFFFFFFFFFF.
Notice that 0xFFFFFFFFFFFFFFFF is the same as 18,446,744,073,709,551,615 and this is the maximum value possible for an unsigned long long, depending on your processor architecture (as gineera said in its comment).
It's not so easy to understand all these things, but keep trying, it will be clearer after the end of this tutorial. At least, I hope it.
In the code part we will see that the number8 variable has a result of 255.
Why? Because 255 is the maximum value of an unsigned char or an uint8_t.
So if we put a value of 256, our result would be 0.
Indeed, after 255 we go back to 0.
For example if we added +1 for each number below, we'd have:
0 (First value of a char or 1 byte) 1 2 3 ... 250 251 252 253 254 255 (Max value of a char or 1 byte) 0 (First value of a char or 1 byte) 1 2 3 ... until 255 (Max value of a char or 1 byte) 0 1 2 3 ... until 255 (Max value of a char or 1 byte) 0 1 2 3 and so on.
So we won't be able to have a value of 256 in a char (or a byte).
If we wanted to have a such value, we would have to use another type, for example an unsigned short or an uint16_t equal to 2 bytes or 16 bits.
Wow, this is still confuse? Let's continue!
Indeed, with an unsigned short, we will be able to use this type up a value of 65535 in decimal
or 0xFFFF in hex.
But in our example, we're going to use a huge value: 18,446,744,073,709,551,615.
And what we'll have will be the max value of each type!
Because this huge value is the maximum value of an unsigned long long.
So every type is set at the maximum value because they are a multiple of each maximum.
2^2 = 4 2^4 = 16 2^8 = 256 2^16 = 65536 2^32 = 4294967296 2^64 = 18446744073709551616
OK, but why the maximum value of a byte is 255 and not 256?
Because (2^8) - 1 = 256 - 1 = 255.
Indeed, our first value is 0 and not 1.
So the second is 1, the third is 2, and so on.
Thus, our last value is 255.
// testValue unsigned long long testValue = 0xFFFFFFFFFFFFFFFF; // 18446744073709551615 // 1 byte -> [0-255] or [0x00-0xFF] uint8_t number8 = testValue; // 255 unsigned char numberChar = testValue; // 255 // 2 bytes -> [0-65535] or [0x0000-0xFFFF] uint16_t number16 = testValue; // 65535 unsigned short numberShort = testValue; // 65535 // 4 bytes -> [0-4294967295] or [0x00000000-0xFFFFFFFF] uint32_t number32 = testValue; // 4294967295 unsigned int numberInt = testValue; // 4294967295 // 8 bytes -> [0-18446744073709551615] or [0x0000000000000000-0xFFFFFFFFFFFFFFFF] uint64_t number64 = testValue; // 18446744073709551615 unsigned long long numberLongLong = testValue; // 18446744073709551615
Now you are able to handle bits and bytes like a professional.
Well done, you've made it.