How do you control significant digits in python?

You can use negative numbers to round integers:

>>> round[1234, -3]
1000.0

Thus if you need only most significant digit:

>>> from math import log10, floor
>>> def round_to_1[x]:
...   return round[x, -int[floor[log10[abs[x]]]]]
... 
>>> round_to_1[0.0232]
0.02
>>> round_to_1[1234243]
1000000.0
>>> round_to_1[13]
10.0
>>> round_to_1[4]
4.0
>>> round_to_1[19]
20.0

You'll probably have to take care of turning float to integer if it's bigger than 1.

answered Aug 5, 2010 at 2:57

13

%g in string formatting will format a float rounded to some number of significant figures. It will sometimes use 'e' scientific notation, so convert the rounded string back to a float then through %s string formatting.

>>> '%s' % float['%.1g' % 1234]
'1000'
>>> '%s' % float['%.1g' % 0.12]
'0.1'
>>> '%s' % float['%.1g' % 0.012]
'0.01'
>>> '%s' % float['%.1g' % 0.062]
'0.06'
>>> '%s' % float['%.1g' % 6253]
'6000.0'
>>> '%s' % float['%.1g' % 1999]
'2000.0'

answered Aug 5, 2010 at 4:24

Peter GrahamPeter Graham

10.9k7 gold badges38 silver badges42 bronze badges

10

If you want to have other than 1 significant decimal [otherwise the same as Evgeny]:

>>> from math import log10, floor
>>> def round_sig[x, sig=2]:
...   return round[x, sig-int[floor[log10[abs[x]]]]-1]
... 
>>> round_sig[0.0232]
0.023
>>> round_sig[0.0232, 1]
0.02
>>> round_sig[1234243, 3]
1230000.0

Stephen Rauch

45.7k30 gold badges105 silver badges126 bronze badges

answered Aug 5, 2010 at 9:49

indgarindgar

6794 silver badges2 bronze badges

8

f'{float[f"{i:.1g}"]:g}'
# Or with Python >> sig_dig[1234243, 3]
    >>> sig_dig[243.3576, 5]

        1230.0
        243.36

answered Mar 26, 2020 at 21:29

LetzerWilleLetzerWille

5,2214 gold badges22 silver badges26 bronze badges

4

Most of these answers involve the math, decimal and/or numpy imports or output values as strings. Here is a simple solution in base python that handles both large and small numbers and outputs a float:

def sig_fig_round[number, digits=3]:
    power = "{:e}".format[number].split['e'][1]
    return round[number, -[int[power] - digits]]

answered Dec 16, 2020 at 18:23

A simple variant using the standard decimal library

from decimal import Decimal

def to_significant_figures[v: float, n_figures: int] -> str:
    d = Decimal[v]
    d = d.quantize[Decimal[[0, [], d.adjusted[] - n_figures + 1]]]
    return str[d.quantize[Decimal[1]] if d == d.to_integral[] else d.normalize[]]

Testing it

>>> to_significant_figures[1.234567, 3]
'1.23'
>>> to_significant_figures[1234567, 3]
'1230000'
>>> to_significant_figures[1.23, 7]
'1.23'
>>> to_significant_figures[123, 7]
'123'

answered Sep 4, 2021 at 21:47

This function takes both positive and negative numbers and does the proper significant digit rounding.

from math import floor

def significant_arithmetic_rounding[n, d]:
    '''
    This function takes a floating point number and the no. of significant digit d, perform significant digits
    arithmetic rounding and returns the floating point number after rounding
    '''
    if n == 0:
        return 0
    else:
        # Checking whether the no. is negative or positive. If it is negative we will take the absolute value of it and proceed
        neg_flag = 0
        if n < 0:
            neg_flag = 1
            n = abs[n]
        
        n1 = n   
        # Counting the no. of digits to the left of the decimal point in the no.
        ld = 0
        while[n1 >= 1]:
            n1 /= 10
            ld += 1
        
        n1 = n
        # Counting the no. of zeros to the right of the decimal point and before the first significant digit in the no.
        z = 0
        if ld == 0:
            while[n1 >> significant_arithmetic_rounding[1234, 3]
1230.0
>>> significant_arithmetic_rounding[123.4, 3]
123.0
>>> significant_arithmetic_rounding[0.0012345, 3]
0.00123
>>> significant_arithmetic_rounding[-0.12345, 3]
-0.123
>>> significant_arithmetic_rounding[-30.15345, 3]
-30.2

answered Dec 7, 2021 at 15:08

Easier to know an answer works for your needs when it includes examples. The following is built on previous solutions, but offers a more general function which can round to 1, 2, 3, 4, or any number of significant digits.

import math

# Given x as float or decimal, returns as string a number rounded to "sig" significant digts
# Return as string in order to control significant digits, could be a float or decimal 
def round_sig[x, sig=2]:
  r = round[x, sig-int[math.floor[math.log10[abs[x]]]]-1]
  floatsig = "%." + str[sig] + "g"
  return "%d"%r if abs[r] >= 10**[sig-1] else '%s'%float[floatsig % r] 

>>> a = [1234, 123.4, 12.34, 1.234, 0.1234, 0.01234, 0.25, 1999, -3.14, -48.01, 0.75]
>>> [print[i, "->", round_sig[i,1], round_sig[i], round_sig[i,3], round_sig[i,4]] for i in a]

1234 -> 1000 1200 1230 1234
123.4 -> 100 120 123 123.4
12.34 -> 10 12 12.3 12.34
1.234 -> 1 1.2 1.23 1.234
0.1234 -> 0.1 0.12 0.123 0.1234
0.01234 -> 0.01 0.012 0.0123 0.01234
0.25 -> 0.2 0.25 0.25 0.25
1999 -> 2000 2000 2000 1999
-3.14 -> -3 -3.1 -3.14 -3.14
-48.01 -> -50 -48 -48.0 -48.01
0.75 -> 0.8 0.75 0.75 0.75

answered Apr 22 at 20:01

chadnchadn

2491 gold badge2 silver badges7 bronze badges

in very cases, the number of significant is depend on to the evaluated process, e.g. error. I wrote the some codes which returns a number according to it's error [or with some desired digits] and also in string form [which doesn't eliminate right side significant zeros]

import numpy as np

def Sig_Digit[x, *N,]:
    if abs[x] < 1.0e-15:
        return[1]
    N = 1 if N ==[] else N[0]
    k = int[round[abs[N]-1]]-int[np.floor[np.log10[abs[x]]]]
    return[k];

def Sig_Format[x, *Error,]:
    if abs[x] < 1.0e-15:
        return['{}']
    Error = 1 if Error ==[] else abs[Error[0]]
    k = int[np.floor[np.log10[abs[x]]]]
    z = x/10**k
    k = -Sig_Digit[Error, 1]
    m = 10**k
    y = round[x*m]/m
    if k < 0:
        k = abs[k]
        if z >= 9.5:
            FMT = '{:'+'{}'.format[1+k]+'.'+'{}'.format[k-1]+'f}'
        else:
            FMT = '{:'+'{}'.format[2+k]+'.'+'{}'.format[k]+'f}'
    elif k == 0:
        if z >= 9.5:
            FMT = '{:'+'{}'.format[1+k]+'.0e}'
        else:
            FMT = '{:'+'{}'.format[2+k]+'.0f}'
    else:
        FMT = '{:'+'{}'.format[2+k]+'.'+'{}'.format[k]+'e}'
    return[FMT]

def Sci_Format[x, *N]:
    if abs[x] < 1.0e-15:
        return['{}']
    N = 1 if N ==[] else N[0]
    N = int[round[abs[N]-1]]
    y = abs[x]
    k = int[np.floor[np.log10[y]]]
    z = x/10**k
    k = k-N
    m = 10**k
    y = round[x/m]*m
    if k < 0:
        k = abs[k]
        if z >= 9.5:
            FMT = '{:'+'{}'.format[1+k]+'.'+'{}'.format[k-1]+'f}'
        else:
            FMT = '{:'+'{}'.format[2+k]+'.'+'{}'.format[k]+'f}'
    elif k == 0:
        if z >= 9.5:
            FMT = '{:'+'{}'.format[1+k]+'.0e}'
        else:
            FMT = '{:'+'{}'.format[2+k]+'.0f}'
    else:
        FMT = '{:'+'{}'.format[2+N]+'.'+'{}'.format[N]+'e}'
    return[FMT]

def Significant[x, *Error]:
    N = 0 if Error ==[] else Sig_Digit[abs[Error[0]], 1]
    m = 10**N
    y = round[x*m]/m
    return[y]

def Scientific[x, *N]:
    m = 10**Sig_Digit[x, *N]
    y = round[x*m]/m
    return[y]

def Scientific_Str[x, *N,]: 
    FMT = Sci_Format[x, *N]
    return[FMT.format[x]]

def Significant_Str[x, *Error,]:    
    FMT = Sig_Format[x, *Error]
    return[FMT.format[x]]

test code:

X = [19.03345607, 12.075, 360.108321344, 4325.007605343]
Error = [1.245, 0.1245, 0.0563, 0.01245, 0.001563, 0.0004603]
for x in X:
    for error in Error:
        print[x,'+/-',error, end='   \t==> ']
        print[' [',Significant_Str[x, error], '+/-', Scientific_Str[error],']']

  

print out:

19.03345607 +/- 1.245       ==>  [ 19 +/-  1 ]

19.03345607 +/- 0.1245      ==>  [ 19.0 +/- 0.1 ]

19.03345607 +/- 0.0563      ==>  [ 19.03 +/- 0.06 ]

19.03345607 +/- 0.01245     ==>  [ 19.03 +/- 0.01 ]

19.03345607 +/- 0.001563    ==>  [ 19.033 +/- 0.002 ]

19.03345607 +/- 0.0004603       ==>  [ 19.0335 +/- 0.0005 ]

12.075 +/- 1.245    ==>  [ 12 +/-  1 ]

12.075 +/- 0.1245       ==>  [ 12.1 +/- 0.1 ]

12.075 +/- 0.0563       ==>  [ 12.07 +/- 0.06 ]

12.075 +/- 0.01245      ==>  [ 12.07 +/- 0.01 ]

12.075 +/- 0.001563     ==>  [ 12.075 +/- 0.002 ]

12.075 +/- 0.0004603    ==>  [ 12.0750 +/- 0.0005 ]

360.108321344 +/- 1.245     ==>  [ 360 +/-  1 ]

360.108321344 +/- 0.1245    ==>  [ 360.1 +/- 0.1 ]

360.108321344 +/- 0.0563    ==>  [ 360.11 +/- 0.06 ]

360.108321344 +/- 0.01245       ==>  [ 360.11 +/- 0.01 ]

360.108321344 +/- 0.001563      ==>  [ 360.108 +/- 0.002 ]

360.108321344 +/- 0.0004603     ==>  [ 360.1083 +/- 0.0005 ]

4325.007605343 +/- 1.245    ==>  [ 4325 +/-  1 ]

4325.007605343 +/- 0.1245       ==>  [ 4325.0 +/- 0.1 ]

4325.007605343 +/- 0.0563       ==>  [ 4325.01 +/- 0.06 ]

4325.007605343 +/- 0.01245      ==>  [ 4325.01 +/- 0.01 ]

4325.007605343 +/- 0.001563     ==>  [ 4325.008 +/- 0.002 ]

4325.007605343 +/- 0.0004603    ==>  [ 4325.0076 +/- 0.0005 ]

answered Sep 17 at 16:11

How do you control significant figures in Python?

' + str[p] + 'e'] % f] allows you to adjust the number of significant digits!

How do you limit significant figures?

If the calculation is an addition or a subtraction, the rule is as follows: limit the reported answer to the rightmost column that all numbers have significant figures in common.

How do you print significant figures in Python?

The “g” format specifier is a general format that can be used to indicate a precision, or to indicate significant digits. To print a number with a specific number of significant digits we do this: print '{0:1.3g}'. format[1./3.]

How do you round to 2 decimal places in Python?

Python's round[] function requires two arguments. First is the number to be rounded. Second argument decides the number of decimal places to which it is rounded. To round the number to 2 decimals, give second argument as 2.

Chủ Đề