Data Types
By the end of this lesson
Choose an appropriate type for a value, and explain why money is not a floating-point number.
A type describes what kind of value a variable holds, and therefore what you are allowed to do with it.
Adding two numbers makes sense. Adding two dates does not, though subtracting them does. Types let the compiler enforce that distinction before your program runs.
The types you will use most often:
- int
- A whole number, positive or negative. Counts, quantities, identifiers.
- decimal
- A precise decimal number. The correct choice for money and anything where exactness matters.
- double
- An approximate decimal number, fast for scientific and graphical calculation. Not for money.
- string
- Text of any length, from a single character to a document.
- bool
- True or false. Nothing else.
- DateTime
- A point in time. Supports comparison and difference, not addition.
Why money must not be a double
This is the single most consequential type decision a beginner makes, and getting it wrong produces bugs that survive to production because they are small enough to look like rounding.
double stores numbers in binary. Some ordinary decimal values, including 0.1, cannot be represented exactly in binary — much as one third cannot be written exactly in decimal. The tiny error is invisible once and significant after ten thousand transactions.
double approximate = 0.1 + 0.2;
decimal exact = 0.1m + 0.2m;
Console.WriteLine(approximate); // 0.30000000000000004
Console.WriteLine(exact); // 0.3
Console.WriteLine(approximate == 0.3); // False
Console.WriteLine(exact == 0.3m); // True- The double result is very slightly off, and the comparison against 0.3 therefore fails.
- decimal is designed for base-10 fractions, so it behaves the way an accountant expects.
- The m suffix marks a literal as decimal rather than double.
Types stop meaningless operations
int quantity = 5;
string label = "5";
int doubled = quantity * 2; // 10 — arithmetic on a number
// string nonsense = label * 2; // will not compile
string repeated = label + label; // "55" — + on strings joins them- Multiplying a number is meaningful. Multiplying text is not, and the compiler refuses.
- Note that + means addition for numbers and joining for strings. This is worth remembering, because 5 + 5 is 10 but "5" + "5" is "55".
Summary
- A type describes what a value is and what operations are valid on it
- Use decimal for money and double only where approximation is acceptable
- "Contains digits" does not mean "is a number" — identifiers like postcodes are text
- The compiler uses types to reject meaningless operations before the program runs
Practice
Attempt each one before opening the solution. Getting it wrong first is how the idea sticks.
Think about it
Think about it
Pick the appropriate type for each: a customer's age, a product price, whether an order has shipped, a postcode, a delivery date, the average rating out of five.
Show solution
Age: int — whole years. Price: decimal — money. Shipped: bool. Postcode: string, even though some contain digits, because it is an identifier with formatting rather than a quantity you calculate with. Delivery date: DateTime. Average rating: decimal or double — decimal if you display it as an exact figure, double if it is purely statistical.
The postcode case is the interesting one. "Contains digits" is not the same as "is a number". If you would never add two of them together, it is probably text.
Try it yourself
Try it yourself
Write a program that adds 0.1 ten times using double, and again using decimal, printing both results. Compare each against 1.
Show solution
The double version accumulates a small error and does not come out exactly equal to 1. The decimal version does.
This is the clearest possible demonstration of why the type choice matters for money.
double d = 0;
decimal m = 0;
for (int i = 0; i < 10; i++)
{
d += 0.1;
m += 0.1m;
}
Console.WriteLine($"double: {d} equals 1? {d == 1.0}");
Console.WriteLine($"decimal: {m} equals 1? {m == 1.0m}");Knowledge check
Nothing is recorded and there is no score. The explanation appears either way.
Saved in this browser only.