rounding
.NET
programming
numerical-precision
software-development

What is the rounding rule when the last digit is 5 in .NET?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In .NET, a value ending in 5 at the rounding position does not always round upward. By default, midpoint values are rounded using ToEven, also called banker's rounding, which means the result goes to the nearest even number rather than always away from zero.

The Default Midpoint Rule

The default behavior of Math.Round uses midpoint rounding to even. That affects numbers that are exactly halfway between two representable rounded results.

csharp
1using System;
2
3Console.WriteLine(Math.Round(2.5));   // 2
4Console.WriteLine(Math.Round(3.5));   // 4
5Console.WriteLine(Math.Round(4.5));   // 4
6Console.WriteLine(Math.Round(5.5));   // 6

Why those results? Because:

  • '2.5 is halfway between 2 and 3, and 2 is even'
  • '3.5 is halfway between 3 and 4, and 4 is even'

This rule reduces cumulative bias in repeated rounding operations, which is why it is a common default in financial and statistical systems.

Use AwayFromZero If You Want Traditional Half-Up Behavior

If your business rule says 2.5 should become 3 and -2.5 should become -3, specify MidpointRounding.AwayFromZero.

csharp
1using System;
2
3Console.WriteLine(Math.Round(2.5, MidpointRounding.AwayFromZero));   // 3
4Console.WriteLine(Math.Round(-2.5, MidpointRounding.AwayFromZero));  // -3

This is often the behavior people expect from school arithmetic, but it is not the default in .NET.

Precision Argument Changes Which Digit Matters

When you round to a specific number of decimal places, the same midpoint rule applies at that digit.

csharp
1using System;
2
3Console.WriteLine(Math.Round(2.25, 1));   // 2.2
4Console.WriteLine(Math.Round(2.35, 1));   // 2.4
5Console.WriteLine(Math.Round(2.45, 1));   // 2.4

At one decimal place:

  • '2.25 is halfway between 2.2 and 2.3, so it goes to 2.2'
  • '2.35 is halfway between 2.3 and 2.4, so it goes to 2.4'

Again, the even final digit wins when the value is exactly at the midpoint.

Be Careful with double

Not every number that looks like a midpoint in decimal is stored exactly as a midpoint in binary floating-point. That matters especially with double.

csharp
1using System;
2
3double value = 2.675;
4Console.WriteLine(Math.Round(value, 2));

Developers are often surprised by cases like this because the internal binary representation may not be exactly 2.675, so the number is not treated as a perfect midpoint when rounding happens.

If decimal precision is important, use decimal rather than double.

csharp
1using System;
2
3decimal value = 2.675m;
4Console.WriteLine(Math.Round(value, 2));  // 2.68

That does not change the midpoint rule itself, but it avoids many binary floating-point surprises.

Pick the Rule That Matches the Domain

There is no universally correct rounding rule for all applications. What matters is choosing the one your domain expects and using it explicitly.

For example:

  • statistical aggregation often prefers ToEven
  • UI display or business rules may prefer AwayFromZero
  • currency calculations often need decimal plus an explicit midpoint mode

If different parts of the codebase silently assume different rules, bugs become very hard to track down.

Common Pitfalls

One common mistake is assuming that any trailing 5 always rounds upward. In .NET, that is not true unless you explicitly request a different midpoint mode.

Another is blaming the rounding rule when the real problem is floating-point representation. A double that looks like a midpoint in source code may not be an exact midpoint internally.

Developers also sometimes rely on defaults in one place and specify AwayFromZero elsewhere. If the application has rounding requirements, make the choice explicit and consistent.

Finally, remember that rounding and formatting are not the same. Displaying a number with two decimal places does not necessarily imply the same rules as numerical rounding in business logic.

Summary

  • The default .NET midpoint rule is ToEven, not always-upward rounding.
  • A value ending in 5 rounds to the nearest even result when it is exactly at the midpoint.
  • Use MidpointRounding.AwayFromZero if your domain expects half-up style behavior.
  • Prefer decimal over double when exact decimal rounding matters.
  • Make the rounding rule explicit when correctness depends on it.

Course illustration
Course illustration