HOWTO · Python
How to Round A Number to Significant Digits in Python
Learn how to round Python numbers to significant digits with round(), math, formatting, Decimal, sigfig, and NumPy.
On this page
To round a number to a chosen number of significant digits, find its decimal magnitude and pass the corresponding decimal-place count to round(). For example, 1,342 rounded to one significant digit becomes 1,000. The built-in function is enough for a single value; use a helper for repeated calculations, formatting when the result should remain text, Decimal when decimal rounding rules matter, or NumPy for arrays.
Round to Significant Digits with Python’s round()
round(number, ndigits) rounds to a number of decimal places. For significant digits, calculate ndigits as digits - 1 - floor(log10(abs(number))). For 1,342 and one significant digit, this is 1 - 1 - 3, or -3, so Python rounds to the nearest thousand.
Run this example:
print(round(1342, -3))
1000
Python uses ties-to-even for halfway cases, so the last retained digit is even when the value is exactly halfway between two rounded values. This is different from always rounding a tie away from zero. Negative ndigits rounds to tens, hundreds, or larger powers of ten. round() returns a number; it does not preserve trailing zeros as a display convention. For floating-point inputs, the stored binary approximation can also affect apparent decimal ties.
Round to Significant Digits with a math Helper
A helper can calculate the decimal-place count from the base-10 magnitude. The following version accepts positive integer digit counts and finite numeric values, and returns zero unchanged. It raises ValueError for an unsupported digit count or a non-finite input, since log10() cannot determine a finite decimal magnitude for those values.
from math import floor, isfinite, log10
def round_significant(value, digits):
if not isinstance(digits, int) or digits < 1:
raise ValueError("digits must be a positive integer")
if not isfinite(value):
raise ValueError("value must be finite")
if value == 0:
return value
places = digits - 1 - floor(log10(abs(value)))
return round(value, places)
print(round_significant(1324, 2))
The formula works for positive and negative finite values because it uses abs(value) to find magnitude, while round() preserves the sign. It follows Python’s ties-to-even rule. Use math.isfinite() to decide whether an input is supported before computing the logarithm; handle NaN and infinities separately if your application needs them.
Round to Significant Digits with String Formatting
The %g format uses its precision as a significant-digit count. With precision p, it uses scientific notation when the decimal exponent is less than -4 or greater than or equal to p; otherwise, it uses ordinary notation. For precision 3, 0.0001 and 999 use ordinary notation, while 0.00001 and 1000 use scientific notation. Formatting returns a string, which is useful when the goal is presentation. Keep that string to preserve its chosen representation; convert it with float() only when later numeric operations are needed. Converting to a number discards display details such as trailing zeros.
For example, "%.3g" % 1324 formats the value with three significant digits. The result is text, and the exact choice between ordinary and scientific notation is made by the formatter.
Round to Significant Digits with sigfig
The third-party sigfig package accepts the number of significant digits through its sigfigs argument. Install the package in your environment before using it. For example, the package call is sigfig.round(1324, sigfigs=2). This is convenient when package behavior and formatting suit your application; it is not necessary for the built-in or helper approaches above.
Round to Significant Digits with decimal.Decimal
Decimal supports decimal arithmetic and an explicit rounding mode. Construct it from a string when the decimal digits in the input matter; converting an existing float cannot recover information that the float did not store. This example scales a finite nonzero decimal to the requested precision and rounds ties away from zero with ROUND_HALF_UP.
from decimal import Decimal, ROUND_HALF_UP
def round_decimal_significant(value, digits):
if not isinstance(digits, int) or digits < 1:
raise ValueError("digits must be a positive integer")
number = Decimal(str(value))
if not number.is_finite():
raise ValueError("value must be finite")
if number.is_zero():
return number
quantum = Decimal(1).scaleb(number.adjusted() - digits + 1)
return number.quantize(quantum, rounding=ROUND_HALF_UP)
print(round_decimal_significant("1324", 2))
The result remains a Decimal. ROUND_HALF_UP is only one policy; choose a mode such as ROUND_HALF_EVEN when it matches the rules of your application. Decimal arithmetic can still be limited by the active context precision, so it does not promise unlimited precision.
Round Arrays to Significant Digits with NumPy
NumPy is useful when the input is an array, but numpy.around() accepts decimal places rather than significant digits. For a nonzero finite value, calculate the decimal-place count with digits - 1 - floor(log10(abs(value))) and pass it to numpy.around(). For an array, compute magnitudes element by element and handle zeros and non-finite values before taking logarithms. NumPy is an additional dependency; this approach follows floating-point rounding behavior and does not preserve display zeros.
The example below rounds only finite, nonzero elements. It leaves zero, NaN, and positive or negative infinity unchanged. The returned value is a NumPy ndarray with floating-point elements. NumPy is an additional dependency, so install it before running this example.
import numpy as np
values = np.array([1234.5, -1234.5, 0.0, np.nan, np.inf, -np.inf])
digits = 3
rounded = values.copy()
finite_nonzero = np.isfinite(values) & (values != 0)
for index in np.flatnonzero(finite_nonzero):
places = digits - 1 - int(np.floor(np.log10(abs(values[index]))))
rounded[index] = np.around(values[index], decimals=places)
print(rounded.tolist())
[1230.0, -1230.0, 0.0, nan, inf, -inf]