Integers and Fixed-Width Types
The logger stores temperatures as whole numbers of tenths of a degree, so 21.5 °C is stored as 215. That avoids floating-point surprises, but raises a new question: how big a number can each integer type hold? In C the honest answer is "it depends on the machine", unless you ask for an exact size.
The rule
int is at least 16 bits; ask
<stdint.h>when you need exact.
The standard guarantees only minimum widths:
| Type | At least | Common on 64-bit Linux and macOS | 64-bit Windows |
|---|---|---|---|
short |
16 bits | 16 | 16 |
int |
16 bits | 32 | 32 |
long |
32 bits | 64 | 32 |
long long |
64 bits | 64 | 64 |
Each type comes in a signed form (negative and positive) and an unsigned form (zero and up, with twice the positive range). <limits.h> tells you the real limits on your machine: INT_MAX, LONG_MIN, UINT_MAX and so on.
Going past the limit behaves differently for the two kinds:
- Unsigned arithmetic wraps around: it is computed modulo 2 to the power of the width. Storing 255 + 1 in a
uint8_tgives 0. That is defined, predictable behaviour. - Signed overflow is undefined behaviour.
INT_MAX + 1has no defined result, and optimising compilers assume it never happens.
When the size matters, for file formats, hardware registers or memory-tight boards, use the fixed-width types from <stdint.h>:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
int16_t temp_tenths = -37; /* exactly 16 bits: -3.7 degrees */
uint16_t readings_today = 1440; /* one per minute */
uint32_t lifetime_readings = 5256000;
printf("%" PRIu32 " readings so far\n", lifetime_readings);int8_t, int16_t, int32_t, int64_t and their uint twins have exactly the width in their name. <inttypes.h> supplies printf macros such as PRIu32 and PRId64, so the right specifier is chosen on every platform.
The shortcut
Size by range. Write down the smallest and largest value the variable will ever hold, then pick the smallest type that covers both, with some headroom.
Temperatures
-40.0 to 85.0 degrees is -400 to 850 in tenths. Negative values are possible, and 16 signed bits cover -32768 to 32767. Choose
int16_t.
Drills
Answer fast — trust the rule.
What is the minimum width the C standard guarantees for int?
After uint8_t level = 255; level = level + 1;, what is level?
int t = INT_MAX; t = t + 1; What is t afterwards?
Which type fits a counter that must reach 5 million, never negative?
Code assumes long is 64 bits. On which common platform does that break?
Remember
- int is at least 16 bits; ask
<stdint.h>when you need an exact width. - Shortcut: size by range, then pick the smallest type that covers it with headroom.
- Trap: unsigned overflow wraps, but signed overflow is undefined behaviour.
