Skip to main content
ANVISoftware Solutions
Lesson 6 of 15Beginner14 min

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.

The same sum with two different types
C#
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

C#
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.

C#
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.

Which type should hold a product price?

Saved in this browser only.