# C++ Data Type Sizes

Size matters! So let’s learn about the actual sizes of C++ data types.
A **Bit** is the smallest unit of storage. It’s 0 or 1, on or off.

A **Byte** is **8** bits.
I wish the world used the French version of the word which is Octet.
The combination of on/off in 8 bits can give us our data values!

A **char** takes up just 1 byte. Below represents 8 bits with different on/off values which represent a char that represents 1. Note that it’s not a value of 1 but a character that reads as 1.

Bit 8 | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 |

0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |

If you use std::bitset, you can see this representation with `bitset<CHAR_BIT>('a')`

.

A **short** takes up 2 bytes or 16 bits. The numeric range of a short would be from 0 to 2^{16} or 65536. This is assuming it’s unsigned. If we want to support negative values, the range shifts (imagine the number line shifting by half) to -32768 to -32767.

An **int** takes up (*assuming you’re on a 32-bit system*) 4 bytes or 32 bits and can store considerably bigger values. You’re looking at 2^{32} which is 4294967296.

Note: you can always use `sizeof()`

to verify the number of bytes your type takes which is subject to your computer architecture.

A **double** is even greater at 8 bytes or 64 bits. At approximately 1.8 * 10^{19}, you’re dealing with massive numerical capacity (and memory implications too). Needless to say, don’t use a double when an int would suffice.

A **float** takes up 4 bytes much like an int. This might seem odd because floats seem to be capable of holding much larger values. This is because a float is encoded to represent exponentials. The IEEE 754 standard dictates that 1 bit determines the sign, 23 bits determine the fraction and 8 bits determine the exponential. The value below represents PI.

Sign (1) | Exponent (2^{8} but -126 to 127) |
Fraction (2^{24}) |

0 | 10000000 | 10010010000111111011011 |

So we’re still employing 32 bits but we can express larger numbers with exponents. The cost of this wider range is accuracy.

A **bool** is one byte. However, this too seems odd at first. A bool is much like a bit - on or off, 0 or 1, false or true. Why do we need a whole byte to express a bool? That’s because the CPU addresses memory in bytes not bits. However with bit fields, we can force members of classes or structures to use less space.