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 )
1000.0with trailing decimal points and/or zeros, which in standard practice indicate far more precision.