How it works
Decimal arithmetic avoids many binary floating-point representation issues for base-ten prices, but it does not choose an accounting policy for the application. A calculation can still produce more fractional digits than a currency's display or settlement rules permit. The program must decide when to round, how many digits to retain, and which midpoint rule applies.
Rounding each line before summing can produce a different total from summing exact intermediate values and rounding once at the end. Neither order is universally correct. The invoice, tax, or payment contract determines the required boundary. Keep the unrounded calculation visible and name the finalization step so a future refactor does not accidentally move that boundary.
Walk through the example. Three identical line calculations each produce 0.335. Rounding every line to two digits with AwayFromZero yields three amounts of 0.34, totaling 1.02. Summing first produces 1.005, which rounds once to 1.01 under the same midpoint rule. The sample prints both values with exactly two decimal places so the one-cent difference is explicit.
Watch the boundary. Formatting with F2 changes the displayed text; it is not a substitute for storing the domain's finalized rounded amount. Also do not mix midpoint policies between different parts of the same workflow without a documented reason. A unit test should capture the chosen policy using values that actually reach midpoint boundaries, not only whole-dollar examples where every strategy agrees.
Practice independently. Model a small invoice with three fractional line totals. Implement two named functions for per-line finalization and invoice-level finalization, then compare them with midpoint and non-midpoint examples. Choose one policy for the invoice and write expected totals by hand. Add a negative adjustment and explain how the chosen midpoint rule applies to it as well as to positive charges.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
decimal[] lines = { 0.335m, 0.335m, 0.335m };
decimal perLine = lines.Sum(x => Math.Round(x, 2, MidpointRounding.AwayFromZero));
decimal atEnd = Math.Round(lines.Sum(), 2, MidpointRounding.AwayFromZero);
Console.WriteLine(perLine.ToString("F2", CultureInfo.InvariantCulture));
Console.WriteLine(atEnd.ToString("F2", CultureInfo.InvariantCulture));
Expected output
1.02 1.01
State both the midpoint rule and the point in the workflow where rounding occurs.