To round a number to 2 decimal places in PowerShell, use [Math]::Round($number, 2). To display it with exactly two decimals, use the format operator, '{0:N2}' -f $number, or .ToString('0.00'):
$price = 19.98765
[Math]::Round($price, 2)
'{0:N2}' -f $price
$price.ToString('0.00')
Output:
19.99
19.99
19.99
They look the same here, but they don’t return the same kind of value, and they don’t always round the same way. I ran every example in PowerShell 7.6 and Windows PowerShell 5.1 and show where they differ.
Round() returns a number, -f returns text
Use Round() when you’ll keep calculating, and -f or ToString() at the end, when you print or export:
$rounded = [Math]::Round(1234.5678, 2)
$formatted = '{0:N2}' -f 1234.5678
"Round() returns a $($rounded.GetType().Name): $rounded"
"-f N2 returns a $($formatted.GetType().Name): $formatted"
"Math still works on the Double: $($rounded * 2)"
Output:
Round() returns a Double: 1234.57
-f N2 returns a String: 1,234.57
Math still works on the Double: 2469.14
N2 also adds a thousands separator. Use F2 for two decimals without commas, or C for currency.
Why 2.5 rounds to 2
[Math]::Round uses banker’s rounding: a value exactly halfway goes to the nearest even number. So 2.5 becomes 2, while 3.5 becomes 4. [int] does the same:
foreach ($n in 0.5, 1.5, 2.5, 3.5) {
'{0} Round: {1} AwayFromZero: {2} [int]: {3} N0: {4}' -f $n,
[Math]::Round($n),
[Math]::Round($n, [MidpointRounding]::AwayFromZero),
[int]$n,
('{0:N0}' -f $n)
}
Output in PowerShell 7:
0.5 Round: 0 AwayFromZero: 1 [int]: 0 N0: 0
1.5 Round: 2 AwayFromZero: 2 [int]: 2 N0: 2
2.5 Round: 2 AwayFromZero: 3 [int]: 2 N0: 2
3.5 Round: 4 AwayFromZero: 4 [int]: 4 N0: 4

Add [MidpointRounding]::AwayFromZero to get the school rule, where 0.5 always rounds up. It’s covered in the MidpointRounding reference.
The N0 column changes between versions
In Windows PowerShell 5.1, format strings round halves away from zero, so its N0 column reads 1, 2, 3, 4. PowerShell 7 rounds them to even, like Round(). That shows up in prices too:
"{0:C}" -f 0.125
"{0:C}" -f 2.345
"{0:N1}" -f 0.25
Output in PowerShell 7:
$0.12
$2.35
0.2
Output in Windows PowerShell 5.1:
$0.13
$2.35
0.3
If a report must match to the cent across versions, round first with AwayFromZero and format after. Don’t let the format string do the rounding.
Use [decimal] for money
Normal numbers are stored in binary, so some decimal values can’t be stored exactly. The d suffix makes a [decimal] literal, which stores cents exactly:
"0.1 + 0.2 as Double: $((0.1 + 0.2).ToString('R'))"
"0.1 + 0.2 as Decimal: $(0.1d + 0.2d)"
Output:
0.1 + 0.2 as Double: 0.30000000000000004
0.1 + 0.2 as Decimal: 0.3
For totals and taxes, cast to [decimal] or use the d suffix, then round once at the end:
$items = 19.99d, 4.25d, 12.10d
$total = 0d
foreach ($price in $items) { $total += $price }
$tax = [Math]::Round($total * 0.0825d, 2, [MidpointRounding]::AwayFromZero)
"Subtotal: {0:C}" -f $total
"Tax: {0:C}" -f $tax
"Total: {0:C}" -f ($total + $tax)
Output:
Subtotal: $36.34
Tax: $3.00
Total: $39.34
I added the prices in a loop because Measure-Object -Sum returns a Double. The tax uses 8.25%, the Texas state and local maximum, and C adds the dollar sign.
Round to the nearest whole number
Round() with no digits rounds to a whole number. Floor always goes down, Ceiling always goes up, and Truncate just drops the decimals:
foreach ($n in 7.8, 7.2, -7.8) {
'{0,5} Round: {1,3} Floor: {2,3} Ceiling: {3,3} Truncate: {4,3}' -f $n,
[Math]::Round($n), [Math]::Floor($n), [Math]::Ceiling($n), [Math]::Truncate($n)
}
Output:
7.8 Round: 8 Floor: 7 Ceiling: 8 Truncate: 7
7.2 Round: 7 Floor: 7 Ceiling: 8 Truncate: 7
-7.8 Round: -8 Floor: -8 Ceiling: -7 Truncate: -7

For -7.8, Floor gives -8 because that’s lower, while Truncate gives -7. Ceiling is handy for counts, like the number of boxes needed for 7.2 boxes’ worth of items.
Truncate to 2 decimals instead of rounding
Truncate has no digits option, so multiply by 100, truncate, then divide:
$rate = 4.3789
"Rounded to 2: $([Math]::Round($rate, 2))"
"Truncated to 2: $([Math]::Truncate($rate * 100) / 100)"
Output:
Rounded to 2: 4.38
Truncated to 2: 4.37
Round Measure-Object results
Measure-Object returns full precision, which looks messy in reports. Round the property you need:
$stats = Get-ChildItem -Path C:\psfaqs\Round -File | Measure-Object -Property Length -Average -Sum
"Raw average: $($stats.Average / 1MB) MB"
"Rounded: $([Math]::Round($stats.Average / 1MB, 2)) MB"
"Total: $('{0:N2}' -f ($stats.Sum / 1MB)) MB"
Output:
Raw average: 1.86879944801331 MB
Rounded: 1.87 MB
Total: 7.48 MB

Round inside Select-Object
For a table, round in a calculated property. The value stays a number, so sorting still works: