Skip to main content

How to Round a Number to a Specific Decimal Place in Batch Script

Rounding is a fundamental operation in data processing, whether you need to display a percentage as 85.7% instead of 85.714285%, or format a price as $19.99. Since Batch only supports integer arithmetic, rounding to a specific decimal place requires either a Scaled Integer workaround or a PowerShell Bridge for true decimal support.

In this guide, we will demonstrate both approaches.

PowerShell provides the [Math]::Round() method for precise rounding.

Implementation Script

@echo off
setlocal

:: Round 85.714285 to 2 decimal places
for /f "usebackq delims=" %%A in (`
powershell -NoProfile -Command "[Math]::Round(85.714285, 2)"
`) do set "result=%%A"

echo Rounded: %result%
pause

Dynamic Input

@echo off
setlocal

set "number=123.456789"
set "places=3"

for /f "usebackq delims=" %%A in (`
powershell -NoProfile -Command "[Math]::Round(%number%, %places%)"
`) do set "result=%%A"

echo.
echo ==========================================
echo ORIGINAL: %number%
echo ROUNDED: %result% (to %places% decimal places^)
echo ==========================================
pause
Rounding Modes

PowerShell's [Math]::Round() uses Banker's Rounding (MidpointRounding.ToEven) by default. This means 0.5 rounds to the nearest even number:

  • [Math]::Round(2.5, 0)2 (rounds down to even)
  • [Math]::Round(3.5, 0)4 (rounds up to even)

To force traditional "Round Half Up" behavior:

for /f "usebackq delims=" %%A in (`
powershell -NoProfile -Command "[Math]::Round(2.5, 0, [MidpointRounding]::AwayFromZero)"
`) do set "result=%%A"

Method 2: Scaled Integer (Pure Batch)

If PowerShell is not available, you can simulate rounding by working in "Scaled Integers." To get one decimal place, multiply by 10; for two decimal places, multiply by 100.

Implementation Script

@echo off
setlocal enabledelayedexpansion

:: Simulate: 100 / 3 = 33.33 (display to 1 decimal place)
set "numerator=100"
set "denominator=3"

:: Scale by 100 for rounding, then extract 1 decimal place
:: Add half the denominator before dividing to achieve rounding
set /a "scaled=(numerator * 100 + denominator / 2) / denominator"

:: Extract whole and fractional parts (scaled has 2 extra digits)
set /a "whole=scaled / 10"
set /a "decimal=scaled %% 10"

echo !numerator! / !denominator! = !whole!.!decimal! (rounded to 1 decimal place^)
pause
How Rounding Works with Scaled Integers

Pure integer division truncates, it always rounds toward zero. To achieve proper rounding, add half the divisor before dividing: (value + divisor / 2) / divisor. This shifts the truncation point so that values at or above the midpoint round up. For example, 100 / 3 = 33 (truncated), but (100 + 1) / 3 = 33 still, while 200 / 3 = 66 (truncated) vs. (200 + 1) / 3 = 67 (rounded).

Overflow Risk

The scaling approach multiplies the numerator by 100 (or more) before dividing. The intermediate product numerator * 100 must fit within Batch's 32-bit signed integer limit (2,147,483,647). For a scale factor of 100, the maximum safe numerator is approximately 21,474,836.

Why Round Numbers?

  1. User-Facing Reports: Displaying CPU Usage: 87.5%% is cleaner than 87.4999999%%.
  2. Financial Calculations: Prices, taxes, and invoices must be rounded to 2 decimal places.
  3. Scientific Data: Sensor readings or statistical results often need to be presented at a specific precision level.

Important Considerations

PowerShell Performance

Each PowerShell call adds overhead (~200–500ms for process startup). For bulk rounding of thousands of values, pass all values to a single PowerShell script instead of calling PowerShell in a loop:

powershell -NoProfile -Command "Get-Content 'values.txt' | ForEach-Object { [Math]::Round([double]$_, 2) }"
Negative Numbers

Rounding behaves differently with negatives depending on the mode. With AwayFromZero, -2.5 rounds to -3 (away from zero), not -2. With the default ToEven mode, -2.5 rounds to -2 (toward even). Be explicit about the rounding mode when working with negative values.

Precision Limits

PowerShell's [double] type can handle about 15–16 significant digits. For financial calculations requiring exact decimal precision beyond this, use [decimal] instead:

powershell -NoProfile -Command "[Math]::Round([decimal]'123.456789012345', 10)"

Conclusion

Rounding numbers to a specific decimal place is essential for producing clean, professional output. While Batch's integer-only math limits native capabilities, the PowerShell bridge provides full decimal precision with any rounding mode you need. By combining the speed of Batch scripting with the mathematical power of PowerShell, you build tools that present data with the exact level of precision your users expect.