Rounding decimals is one of those tasks you encounter constantly in C# development — financial calculations, UI displays, data exports. I've been working with .NET for years, and I still see developers trip up on midpoint rounding behavior or mix up decimal and double types.
Let me show you how to round to 2 decimal places properly, plus some gotchas I wish someone had told me earlier.
using System;
// Install via NuGet: Install-Package System
decimal price = 19.996m;
decimal rounded = Math.Round(price, 2);
Console.WriteLine(rounded); // 20.00
How Do I Round a Decimal to 2 Decimal Places?
The Math.Round() method is your go-to. It takes two arguments: the number and how many decimal places you want.
decimal orderTotal = 157.846m;
decimal finalPrice = Math.Round(orderTotal, 2);
// Result: 157.85
This works for most scenarios. The m suffix makes it a decimal literal — critical for financial calculations where precision matters.
What About Rounding Double Values?
Same method, different type:
double measurement = 3.14519;
double rounded = Math.Round(measurement, 2);
// Result: 3.15
Here's the key difference: double is a floating-point type optimized for performance. Use it for scientific calculations or when you need speed over precision. decimal is slower but accurate to 28-29 significant digits — essential for money.
I learned this the hard way on a payment processing project. We used double for currency and ended up with $0.01 discrepancies on large batches. Switching to decimal fixed it immediately.
Why Is 2.345 Rounding to 2.34 Instead of 2.35?
This one catches everyone. By default, C# uses "banker's rounding" (also called round-to-even). When a value is exactly halfway between two numbers, it rounds to the nearest even number:
decimal value1 = 2.345m;
decimal value2 = 2.355m;
Math.Round(value1, 2); // 2.34 (rounds down to even)
Math.Round(value2, 2); // 2.36 (rounds up to even)
This minimizes cumulative rounding errors in large datasets. But if you need traditional "away from zero" rounding:
decimal halfway = 2.345m;
decimal rounded = Math.Round(halfway, 2, MidpointRounding.AwayFromZero);
// Result: 2.35
MidpointRounding.AwayFromZero makes .5 always round up. I use this for customer-facing displays where people expect standard rounding rules.
How Do I Round for Display Without Changing the Value?
If you just need to show 2 decimal places in a string but keep the original value:
decimal amount = 99.9m;
string display = amount.ToString("F2");
// Result: "99.90"
The "F2" format specifier forces 2 decimal places with zero-padding. The original amount variable stays 99.9.
For string interpolation:
decimal tax = 5.3m;
Console.WriteLine($"Tax: ${tax:F2}");
// Output: Tax: $5.30
What If I Need to Round Currency for PDF Reports?
This is where I use IronPDF constantly. When generating invoices or financial reports, you need rounded values rendered cleanly in PDFs.
using IronPdf;
// Install via NuGet: Install-Package IronPdf
decimal subtotal = 1234.567m;
decimal roundedSubtotal = Math.Round(subtotal, 2);
var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/ironpdf-2021-chrome-rendering-engine-eap-a-game-changer-for-pdf-generation/)();
var html = $@"
<h1>Invoice</h1>
<p>Subtotal: ${roundedSubtotal:F2}</p>
";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("invoice.pdf");
IronPDF uses a Chrome rendering engine, so your HTML/CSS renders pixel-perfect. I've tried other libraries that mangle table layouts or lose formatting. With IronPDF, what you see in the browser is what you get in the PDF.
The full tutorial on IronPDF covers more advanced scenarios like rendering MVC views or Razor pages to PDF.
Can I Round Negative Numbers?
Yes, the same way:
decimal loss = -45.678m;
decimal rounded = Math.Round(loss, 2);
// Result: -45.68
With AwayFromZero, negative midpoints round toward negative infinity:
decimal negative = -2.345m;
Math.Round(negative, 2, MidpointRounding.AwayFromZero);
// Result: -2.35 (away from zero means more negative)
What About Rounding to Other Decimal Places?
Just change the second parameter:
decimal pi = 3.14159265m;
Math.Round(pi, 0); // 3
Math.Round(pi, 1); // 3.1
Math.Round(pi, 3); // 3.142
Math.Round(pi, 4); // 3.1416
Should I Use Math.Ceiling or Math.Floor?
Those always round up or down, regardless of the fractional part:
decimal value = 2.1m;
Math.Ceiling(value); // 3
Math.Floor(value); // 2
Math.Round(value, 0); // 2
I use Ceiling for page count calculations (partial pages count as full pages) and Floor when calculating bulk discounts (only full units qualify).
For precision rounding to 2 decimals, stick with Math.Round().
Quick Reference
| Scenario | Method |
|---|---|
| Standard rounding | Math.Round(value, 2) |
| Always round .5 up | Math.Round(value, 2, MidpointRounding.AwayFromZero) |
| Display only | value.ToString("F2") |
| Always round up | Math.Ceiling(value) |
| Always round down | Math.Floor(value) |
The key is knowing when you need precision (decimal) versus performance (double), and understanding midpoint behavior. Most financial bugs I've debugged trace back to one of those two things.
Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.
Top comments (0)