5.1.2C Programming

Data types — char, short, int, long, float, double, size_t

2,237 words10 min readdifficulty · medium

WHY do data types exist?


WHAT are the types? (the 20% that gives 80%)


HOW do we DERIVE the range of an integer type?

We derive it from first principles — counting bit patterns.

Unsigned (unsigned char, size_t, …): every pattern is a non-negative value. range=[0, 2n1]\text{range} = [\,0,\ 2^n - 1\,] Why 1-1? Because zero eats one of the 2n2^n slots, so the largest value is one less than the count.

Signed (two's complement, what C uses in practice): one bit's "weight" is made negative so we can encode negatives. We split the 2n2^n patterns into negatives and non-negatives: range=[2n1,  2n11]\text{range} = [\,-2^{\,n-1},\ \ 2^{\,n-1} - 1\,]

Why this is asymmetric (one more negative than positive)? The pattern 1000…0 is reserved for the most-negative value; zero sits on the positive side, "using up" one positive slot. So you get 2n12^{n-1} negatives but only 2n112^{n-1}-1 positives.


HOW does float/double store a number? (IEEE-754)


What is size_t?

Figure — Data types — char, short, int, long, float, double, size_t

Worked example: predict the output


Active Recall

Recall Quick self-test (cover the answers)
  • Range of an nn-bit signed integer? → [2n1, 2n11][-2^{n-1},\ 2^{n-1}-1]
  • Only type whose sizeof is fixed by the standard? → char (== 1)
  • Why ~7 digits for float? → 24 mantissa bits × log102\log_{10}2
  • Type returned by sizeof? → size_t (unsigned)
  • 0.1+0.2 == 0.3? → false (binary rounding)
With n bits, how many distinct bit patterns exist?
2n2^n
Range of an n-bit unsigned integer?
[0, 2n1][0,\ 2^n-1]
Range of an n-bit signed (two's complement) integer?
[2n1, 2n11][-2^{n-1},\ 2^{n-1}-1]
Why is signed range asymmetric (one more negative)?
The pattern 1000…0 encodes the most-negative value, and 0 sits on the positive side using a slot.
Range of signed char (8 bits)?
[128,127][-128, 127]
Range of unsigned char (8 bits)?
[0,255][0, 255]
Range of a 32-bit int?
[2147483648, 2147483647][-2147483648,\ 2147483647]
Which type's sizeof is guaranteed to be 1 by the standard?
char
Ordering of integer sizes guaranteed by C?
char ≤ short ≤ int ≤ long ≤ long long
IEEE-754 float bit layout (sign/exp/mantissa)?
1 / 8 / 23, bias 127
IEEE-754 double bit layout?
1 / 11 / 52, bias 1023
Value formula of a normalized IEEE-754 number?
(1)s×(1.f)2×2ebias(-1)^s \times (1.f)_2 \times 2^{e-\text{bias}}
Why does float have ~7 decimal digits of precision?
24 mantissa bits × log10(2) ≈ 7.2
Approx decimal digits of double precision?
~15–16 (53 bits × log10(2))
What is size_t?
An unsigned type large enough to hold any object's size; returned by sizeof.
printf format specifier for size_t?
%zu
Why is "size_t i; i >= 0" a bug in a countdown loop?
Unsigned can never be < 0, so it's always true → infinite loop and wrap-around.
Why is 0.1+0.2 != 0.3 in C?
0.1 and 0.2 have no finite binary representation, so they're rounded.

Recall Feynman: explain to a 12-year-old

Imagine little labelled boxes. A char box is tiny — it fits one letter or a small number. An int box is bigger — it fits normal counting numbers. A double box is special: instead of just counting, it remembers a number in "scientific notation" form (some digits + where the dot goes), so it can hold really big or really tiny numbers but with only about 15 trustworthy digits. size_t is the box we use to say "how big is this thing?" — and since something's size is never negative, that box only holds 0 and up. The label on the box tells the computer how big the box is and how to read what's inside.


Connections

  • Two's Complement Representationwhy signed ranges are asymmetric
  • Integer Overflow and Undefined Behaviour — what happens past the range
  • IEEE-754 Floating Point — full mantissa/exponent derivation
  • sizeof Operator — how to query sizes at compile time
  • Type Conversion and Promotion — what happens when types mix
  • Pointers and Addresses — why size_t matches pointer width

Concept Map

needs

specifies

specifies

specifies

as int char or float

derives

non-negative

includes negatives

uses

measured by

enforces

only fixed sizeof char equals 1

Memory raw bytes 0s and 1s

Data type contract

Size in bytes

Interpretation lens

Range of values

n bits give 2^n patterns

Unsigned range 0 to 2^n-1

Signed range -2^n-1 to 2^n-1 -1

Two's complement

sizeof operator

char le short le int le long

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, C me har variable ka ek data type hota hai, aur ye basically ek contract hai jo compiler ko do cheez batata hai: kitne bytes ki memory lena hai, aur un bits ko kaise padhna hai (integer, character, ya floating number). Same bit pattern 0100 0001 ko int samjho to 65, char samjho to 'A' — type hi decide karta hai matlab. Isiliye type ko ek "lens" samajh sakte ho.

Integer types ka range rote-ratane ki zaroorat nahi, derive karo. nn bits se 2n2^n patterns bante hain. Agar unsigned hai to range [0,2n1][0, 2^n-1] (zero ek slot kha jaata hai isliye 1-1). Agar signed (two's complement) hai to range [2n1,2n11][-2^{n-1}, 2^{n-1}-1] — yaani ek negative number zyada hota hai positive se, kyunki pattern 1000...0 sabse chhota negative banata hai. Isse signed char ka range [128,127][-128,127] aur int ka [2.1[-2.1 billion, +2.1+2.1 billion]] nikalta hai. Yaad rakho: standard sirf sizeof(char)==1 guarantee karta hai, int har jagah 4 bytes ho — ye assume mat karna.

float aur double ko samjho scientific notation jaisa: sign + mantissa (digits) + exponent (scale). Formula: (1)s×1.f×2ebias(-1)^s \times 1.f \times 2^{e-bias}. float me 24 mantissa bits → 24×0.301724 \times 0.301 \approx 7 decimal digits ki precision, double me ~15-16. Isiliye 0.1 + 0.2 == 0.3 false aata hai — kyunki 0.1 binary me exactly store hi nahi hota, thoda rounding error aa jaata hai. Float compare karne ke liye fabs(a-b) < epsilon use karo, kabhi == nahi.

Last me size_t: ye ek unsigned type hai jo sizeof aur strlen return karte hain, aur itna bada hota hai ki kisi bhi object ka size store kar sake (64-bit machine pe 8 bytes). Size kabhi negative nahi hota, isiliye unsigned. Ek common bug: size_t i use karke i >= 0 likhoge to wo hamesha true rahega → infinite loop. Print karne ke liye %zu lagao. Bas itna samajh lo to data types ka 80% kaam ho gaya.

Go deeper — visual, from zero

Test yourself — C Programming

Connections