Created: September-12, 2021 | Updated: October-12, 2021 Rounding the number means replacing a number with an approximate value that is close to it. We can also round numbers to the required significant figure. In this article, we will round a number to a specific
significant digit in Python. The We can use a negative number to round the integer to the significant floor value by assigning it to the For example, if we wish to round to one significant digit, we specify the value as [1-total digits] in the See the following code. Output: This method is an improvement on the previously discussed function. We can create a simple
user-defined function to make this more convenient. We won’t have to specify the negative number in this method’s See the code below. Output: In Python, the This method returns a string. So, we have to convert the string number back to a float or integer value after formatting it. For example, Output:round[]
Function to Round a Number to the Given Significant Digit in Pythonmath
Module to Round a Number to the Given Significant Digit in Pythonsigfig
Module to Round a Number to the Given Significant Digit in PythonUse the
round[]
Function to Round a Number to the Given Significant Digit in Pythonround[]
function rounds the given floating values to the nearest integer or specified decimal position.round[]
function. This negative number to be specified depends on
the required significant digits.round[]
function.x = round[1342, -3]
print[x]
1000
Use the
math
Module to Round a Number to the Given Significant Digit in Pythonround[]
function. We will replace this using a combination of the math.floor[]
function and the math.log10[]
function.from math import log10 , floor
def round_it[x, sig]:
return round[x, sig-int[floor[log10[abs[x]]]]-1]
print[round_it[1324,1]]
1000
Use String Formatting to Round a Number to the Given Significant
Digit in Python
%g
specifier in string formats a float rounded to a specified significant figure. If the magnitude of the final number is huge, then it shows it in scientific notation.x = float['%.1g' % 1324]
print[x]
1000.0
Use the sigfig
Module to Round a Number to the Given Significant Digit in Python
The sigfig
module is the best fit for rounding the numbers to a significant digit as it minimizes the hassle of creating a user-defined function and simplifies the code.
We can specify the number of significant digits in this module’s round[]
function.
See the following example.
from sigfig import round
print[round[1324, sigfigs = 1]]
Output:
1000
- 1 Rounding Off to a Whole Number
- 1.1 Rounding Down
- 1.2 Rounding Up
- 1.3 Rounding Towards Zero
- 1.4 Rounding Away from Zero
- 2 Rounding Off to a
Number of Decimal Places
- 2.1 Rounding Using String Formatting
- 3 Rounding Off to a Number of Significant Figures
- 3.1 Customising Sig Fig Notation
- 4 Rounding Using Engineering Notation
- 4.1 Customising Engineering Notation
⇦ Back
Rounding Off to a Whole Number
Python has a built-in function round[]
that will, as the name suggests, round a number
off:
unrounded = 5.99
rounded = round[unrounded]
print[rounded]
## 6
Note that, by default, this uses the round half to even rule for tie-breaking multiples of 0.5. In other words, any number that ends in “.5” gets rounded to the nearest EVEN whole number:
# 2.5 gets rounded DOWN
print[round[2.5]]
## 2
# 3.5 gets rounded UP
print[round[3.5]]
## 4
This is true even for negative numbers:
print[round[-2.5]]
## -2
This method of rounding off is known as statistician’s rounding and avoids both a positive/negative bias and a bias towards/away from zero
Rounding Down
The built-in math
library contains the floor[]
function that will round numbers ‘towards the floor’ [ie towards negative infinity]:
import math
negative_example = math.floor[-2.9]
positive_example = math.floor[2.9]
print[negative_example, positive_example, sep=', ']
## -3, 2
Rounding Up
The complement to floor[]
is ceil[]
which will round numbers ‘towards the ceiling’ [ie towards positive infinity]:
negative_example = math.ceil[-2.9]
positive_example = math.ceil[2.9]
print[negative_example, positive_example, sep=', ']
## -2, 3
Rounding Towards Zero
The trunc[]
function truncates a number, which means that it throws away the part after the decimal point. This is equivalent to rounding towards zero:
negative_example = math.trunc[-2.9]
positive_example = math.trunc[2.9]
print[negative_example, positive_example, sep=', ']
## -2, 2
Rounding Away from Zero
There is no single function to do this in math
[not even in numpy
]! However, here’s a quick custom function you can use:
def round_away_from_zero[x]:
"""Round a number x away from 0."""
return math.ceil[abs[x]] * math.copysign[1, x]
negative_example = round_away_from_zero[-2.9]
positive_example = round_away_from_zero[2.9]
print[negative_example, positive_example, sep=', ']
## -3.0, 3.0
The abs[]
function takes the absolute
value of the un-rounded number [ie makes it positive if it’s negative], rounds it up with ceil[]
then multiplies that answer by either -1 or 1 using the copysign[]
function to copy the sign of the original number.
Rounding Off to a Number of Decimal Places
The round[]
function can take a second argument, namely the number of decimal places you want to round off to:
unrounded = 6.283185
rounded = round[unrounded, 3]
print[rounded]
## 6.283
Again, this uses statistician’s rounding:
# Round DOWN to 6.28318
print[round[6.283185, 5]]
## 6.28318
Rounding Using String Formatting
Another method for rounding off is to use the .xf
notation with formatted strings [usually these will be ‘f-strings’ - see this page for more info - but you can also use this notation with the older .format[]
method or
%-sign notation]. .xf
will round a floating-point number off to x places after the decimal point and it can be used with f-strings as follows:
unrounded = 6.283185
rounded = f'The number rounded to 3 decimal places is: {unrounded:.3f}'
print[rounded]
## The number rounded to 3 decimal places is: 6.283
Note that the result is a string not a number! So you can’t do any further calculation with it when using this method.
Rounding Off to a Number of Significant Figures
Instead of
rounding off to a certain number of decimal places we often want to round off to a certain number of significant figures - digits excluding leading zeroes. A useful library that will do this is sigfig
which can be installed from the terminal with:
# If you have a version of Python that isn't 3.9 use those version numbers instead
python3.9 -m pip install sigfig
This includes a new implementation of the round[]
function that overwrites the built-in one. It can round off to a given number of decimal places using the decimals
keyword argument like so:
import sigfig
unrounded = 1.2345
rounded = sigfig.round[unrounded, decimals=3]
print[f'{1.2345} becomes {rounded}']
## 1.2345 becomes 1.235
Note that this function rounds half away from zero, also known as commercial rounding: 1.2345 gets rounded to 1.235 as opposed to statistician’s rounding which would make it 1.234
This implementation of round[]
can also round off to a given number of significant figures via the sigfigs
keyword argument:
unrounded = 1.2345
rounded = sigfig.round[unrounded, sigfigs=3]
print[f'{1.2345} becomes {rounded}']
## 1.2345 becomes 1.23
Note that exponential notation is preserved unless you convert to a string before invoking the function:
unrounded = 1.2345e-7
exponential = sigfig.round[unrounded, sigfigs=3]
floating = sigfig.round[str[unrounded], sigfigs=3]
print[f'{1.2345e-7} becomes {exponential} or {floating}']
## 1.2345e-07 becomes 1.23e-07 or 0.000000123
This
function can also incorporate uncertainty using the uncertainty
keyword:
unrounded = 1.2345
rounded = sigfig.round[unrounded, uncertainty=0.0002]
print[f'{1.2345} becomes {rounded}']
## 1.2345 becomes 1.2345 ± 0.0002
And, finally, it can use different representations of uncertainty:
# Estimate Newton's gravitational constant
print['G =', sigfig.round['6.67430', '0.00015', format='Drake'], '×10^−11 m3⋅kg−1⋅s−2']
## G = 6.674 30[15] ×10^−11 m3⋅kg−1⋅s−2
Customising Sig Fig Notation
If you are absolutely set on using statistician’s rounding [or if you want to make any other modifications to how the sigfig
package does its rounding], or if you only want to use built-in packages instead of relying
on external dependencies, you can re-create the function yourself. This has been done below:
from decimal import Decimal, getcontext
def round_to_sig_figs[x, sigfigs]:
"""Round a number off to a given number of significant figures."""
# A special case is if the number is 0
if float[x] == 0.0:
output = '0' * sigfigs
# Insert a decimal point
output = output[0] + '.' + output[1:]
return output
# A special case is if the number is 'nan'
if np.isnan[x]:
return 'None'
# Set the precision
getcontext[].prec = sigfigs
rounded = Decimal[x]
# The precision only kicks in when an arithmetic operation is performed
rounded = rounded * 1
# Remove scientific notation
# [if the order of magnitude of the number is larger than the number of
# significant figures, the number will have been converted to scientific
# notation]
rounded = float[rounded]
# Convert to string
output = str[rounded]
# Count the number of significant figures
sigfigs_now = len[output.replace['-', ''].replace['.', ''].lstrip['0']]
# Remove trailing zero if one exists and it is not necessary
if [[sigfigs_now > sigfigs] and [output.endswith['.0']]]:
output = output.removesuffix['.0']
# Add trailing zeroes if necessary
if sigfigs_now < sigfigs:
discrepancy = sigfigs - sigfigs_now
# Append a decimal point if necessary
if '.' not in output:
output = output + '.'
# Add trailing zeroes
output = output + '0' * discrepancy
return output
Let’s test it:
unrounded = 1.2345
rounded = round_to_sig_figs[unrounded, 4]
print[f'{1.2345} becomes {rounded}']
## 1.2345 becomes 1.234
Rounding Using Engineering Notation
Another useful library to have is engineering_notation
. It can be installed from the terminal with:
# If you have a version of Python that isn't 3.9 use those version numbers instead
python3.9 -m pip install engineering_notation
This library contains the EngNumber[]
function which converts a number into ‘engineering notation’ [ie it represents it as a multiple of
\[10^x\] or of \[1/10^x\] where \[x\] is a multiple of 3] using the usual SI units. It then rounds off to a given precision [number of decimal place; 2 by default] or to a given level of significance:
from engineering_notation import EngNumber
# Represent a large number in engineering notation with a unit
# Use default rounding [to 2 decimal places]
raw = 12345
formatted = EngNumber[raw]
print[f'{raw} becomes {formatted}']
## 12345 becomes 12.34k
# Represent a small number in engineering notation with a unit
# Round to 1 decimal place
raw = 0.012345
formatted = EngNumber[raw, precision=1]
print[f'{raw} becomes {formatted}']
## 0.012345 becomes 12.3m
# Represent a number in engineering notation
# Round to 4 significant figures
raw = 6.283185
formatted = EngNumber[raw, significant=4]
print[f'{raw} becomes {formatted}']
## 6.283185 becomes 6.283
Customising Engineering Notation
If you want to tweak the output of EngNumber[]
you can copy the function’s source code from
GitHub and edit it yourself. Here’s an example of exactly that: the EngNumber[]
function re-moulded into a new function round_engineering[]
that represents the output in a variant of exponential notation:
from decimal import Decimal
def round_engineering[value, precision=2, significant=0]:
"""
Round and convert to an exponential format that is a multiple of 3.
:return: A string representing the engineering number
"""
number = Decimal[str[value]]
# Since the Decimal class only really converts numbers that are very small
# into engineering notation we will simply make all numbers small numbers.
# We can then take advantage of the Decimal class
num_str = number * Decimal['10e-25']
num_str = num_str.to_eng_string[].lower[]
base, exponent = num_str.split['e']
if significant > 0:
if abs[Decimal[base]] >= 100.0:
base = str[round[Decimal[base], significant - 3]]
elif abs[Decimal[base]] >= 10.0:
base = str[round[Decimal[base], significant - 2]]
else:
base = str[round[Decimal[base], significant - 1]]
else:
base = str[round[Decimal[base], precision]]
if 'e' in base.lower[]:
base = str[int[Decimal[base]]]
# Remove trailing decimals
# //stackoverflow.com/questions/3410976/how-to-round-a-number-to-significant-figures-in-python
# //stackoverflow.com/questions/11227620/drop-trailing-zeros-from-decimal
if '.' in base:
base = base.rstrip['.']
# Remove trailing .00 in precision 2
if precision == 2 and significant == 0:
if '.00' in base:
base = base[:-3]
# Scale the exponent back to normal
exponent = str[int[exponent] + 24]
# Format the exponent
if exponent == '0':
exponent_str = ''
else:
exponent_str = '×10^' + exponent
return base + exponent_str
Here’s how it’s used:
numbers = [
1,
12,
123,
1234,
12345,
123456,
0.1234,
1.234,
12.34,
123.4,
1234,
]
for number in numbers:
print[f'{number:>7} becomes {round_engineering[number, significant=3]}']
## 1 becomes 1.00
## 12 becomes 12.0
## 123 becomes 123
## 1234 becomes 1.23×10^3
## 12345 becomes 12.3×10^3
## 123456 becomes 123×10^3
## 0.1234 becomes 123×10^-3
## 1.234 becomes 1.23
## 12.34 becomes 12.3
## 123.4 becomes 123
## 1234 becomes 1.23×10^3
⇦ Back