Floating-Point Numbers

Vaibhav • September 11, 2025

In the previous article, we explored integer types-perfect for whole numbers like counts, scores, and indexes. But what if you need to represent fractions, measurements, or currency? That’s where floating-point types come in. In this article, we’ll introduce the three main floating-point types in C#: float, double, and decimal. We’ll explain how they store numbers, how they differ in precision, and why choosing the right one is critical-especially in financial applications.

What Are Floating-Point Numbers?

Floating-point numbers represent real numbers-those with decimal points. They’re used when you need to store values like temperature, distance, price, or scientific measurements. Unlike integers, which store exact whole numbers, floating-point types approximate values using a format that balances range and precision.

C# provides three floating-point types:

// Declaration examples
float piApprox = 3.14f;
double precisePi = 3.14159265358979;
decimal price = 19.99m;

Notice the suffixes: f for float, m for decimal. Without them, the compiler assumes double by default.

Floating-point types are value types, just like integers. They store their data directly in memory and are optimized for performance.

Understanding Precision and Range

Each floating-point type has a different balance of precision (how many digits it can accurately store) and range (how large or small the values can be). Here’s a quick overview:

Type Size Precision Range
float 4 bytes ~7 digits ±1.5 × 10-45 to ±3.4 × 1038
double 8 bytes ~15-16 digits ±5.0 × 10-324 to ±1.7 × 10308
decimal 16 bytes ~28-29 digits ±1.0 × 10-28 to ±7.9 × 1028

float and double use binary floating-point representation, which is fast and efficient but can introduce rounding errors. decimal uses a base-10 representation, making it ideal for financial and monetary calculations where precision is critical.

Use float and double for scientific or engineering data. Use decimal for money, prices, and anything involving currency.

Precision Differences in Practice

Let’s look at how precision affects calculations. Consider this example:

// Using float
float a = 1.0f / 3.0f;
Console.WriteLine(a); // Output: 0.3333333

// Using double
double b = 1.0 / 3.0;
Console.WriteLine(b); // Output: 0.3333333333333333

// Using decimal
decimal c = 1.0m / 3.0m;
Console.WriteLine(c); // Output: 0.3333333333333333333333333333

Each type gives a different level of precision. float rounds off after 7 digits, double goes further, and decimal maintains high precision. This matters when you’re doing repeated calculations or comparing values.

Even simple operations like 0.1 + 0.2 may not equal 0.3 when using float or double. That’s due to how binary floating-point works.

Common Pitfalls in Financial Calculations

One of the most frequent mistakes beginners make is using float or double for money. These types can introduce rounding errors that accumulate over time-leading to incorrect totals, mismatched invoices, or failed audits.

// Incorrect: using double for currency
double price = 19.99;
double total = price * 3;
Console.WriteLine(total); // Output: 59.969999999999999

// Correct: using decimal
decimal priceDec = 19.99m;
decimal totalDec = priceDec * 3;
Console.WriteLine(totalDec); // Output: 59.97

The difference may seem small, but in financial systems, even a cent matters. Always use decimal for currency to avoid these issues.

Never use float or double for money. Use decimal to ensure accurate and predictable results.

Arithmetic and Comparison

Floating-point types support all standard arithmetic operations: addition, subtraction, multiplication, division, and modulus. But comparisons can be tricky due to rounding errors.

// Comparison trap
double x = 0.1 + 0.2;
Console.WriteLine(x == 0.3); // False

// Safer approach
bool isClose = Math.Abs(x - 0.3) < 0.00001;
Console.WriteLine(isClose); // True

Instead of checking for exact equality, compare the difference and see if it’s within a small tolerance. This technique is common in scientific and graphics programming.

Default Values and Initialization

Like other value types, floating-point variables have default values:

// Default values
float f;     // 0.0f
double d;    // 0.0
decimal m;   // 0.0m

If you declare a floating-point field in a class without initializing it, it will default to zero. This is useful when you’re accumulating totals or performing calculations.

Literal Formatting and Readability

You can use underscores in numeric literals to improve readability, especially for large or precise values:

// Readable literals
double distance = 1_234_567.89;
decimal salary = 75_000.00m;

These underscores are ignored by the compiler but make your code easier to read and maintain.

Choosing the Right Type

Picking the right floating-point type depends on your use case:

  • Use float for graphics, sensors, and approximate values.
  • Use double for scientific, statistical, or engineering data.
  • Use decimal for financial, accounting, and currency-related data.

Remember, precision matters. Don’t use float just because it’s smaller-if your application needs accuracy, choose accordingly.

Summary

Floating-point types allow you to represent real numbers in your programs. C# provides three options-float, double, and decimal-each with different precision and range characteristics. Understanding how they work helps you avoid subtle bugs and write reliable code.

In this article, you learned:

  • What floating-point numbers are and why they matter
  • The differences between float, double, and decimal
  • How precision affects calculations and comparisons
  • Why decimal is essential for financial applications
  • How to choose the right type for your scenario

In the next article, we’ll explore Boolean Logic-how to represent true/false values, make decisions, and lay the foundation for control flow in your programs.