You can use negative numbers to round integers: >>> round(1234, -3) 1000.0. Thus if you need only most significant digit:
Home
Public
Questions
Tags
Users
Collectives
ExploreCollectives
FindaJob
Jobs
Companies
Teams
StackOverflowforTeams
–Collaborateandshareknowledgewithaprivategroup.
CreateafreeTeam
WhatisTeams?
Teams
CreatefreeTeam
CollectivesonStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
Learnmore
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
Learnmore
HowtoroundanumbertosignificantfiguresinPython
AskQuestion
Asked
11years,4monthsago
Active
5daysago
Viewed
263ktimes
182
45
IneedtoroundafloattobedisplayedinaUI.e.g,toonesignificantfigure:
1234->1000
0.12->0.1
0.012->0.01
0.062->0.06
6253->6000
1999->2000
IsthereanicewaytodothisusingthePythonlibrary,ordoIhavetowriteitmyself?
pythonmathroundingsignificant-digits
Share
Follow
editedAug14at2:18
smci
28.2k1717goldbadges106106silverbadges142142bronzebadges
askedAug5'10at0:48
PeterGrahamPeterGraham
10.5k77goldbadges3636silverbadges4141bronzebadges
4
2
Areyoujustformattingtheoutput?Areyouaskingaboutthis?docs.python.org/library/stdtypes.html#string-formattingorthis?docs.python.org/library/string.html#string-formatting
– S.Lott
Aug5'10at0:53
whatoutputdoyouexpectfor0.062and6253?
– lamirap
Aug5'10at0:58
Thepackageto-precisionnowdoesthis.Mypostedanswerdetailshowthisapplies.
– WilliamRusnack
May23'17at12:13
1
Theanswerby@Falkengivestherequestedresults,whicharecorrect.Nearlyalltheothersgiveresultslike1000.0withtrailingdecimalpointsand/orzeros,whichinstandardpracticeindicatefarmoreprecision.
– nealmcb
Sep10'20at16:42
Addacomment
|
23Answers
23
Active
Oldest
Votes
167
Youcanusenegativenumberstoroundintegers:
>>>round(1234,-3)
1000.0
Thusifyouneedonlymostsignificantdigit:
>>>frommathimportlog10,floor
>>>defround_to_1(x):
...returnround(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'llprobablyhavetotakecareofturningfloattointegerifit'sbiggerthan1.
Share
Follow
editedJan7'16at6:43
TobiasKienzler
22.7k2121goldbadges115115silverbadges210210bronzebadges
answeredAug5'10at2:57
EvgenyEvgeny
2,63522goldbadges1616silverbadges1818bronzebadges
13
3
Thisisthecorrectsolution.Usinglog10istheonlyproperwaytodeterminehowtoroundit.
– Wolph
Aug5'10at3:23
85
round_to_n=lambdax,n:round(x,-int(floor(log10(x)))+(n-1))
– RoyHyunjinHan
Apr30'13at19:30
31
Youshoulduselog10(abs(x)),otherwisenegativenumberswillfail(Andtreatx==0separatelyofcourse)
– TobiasKienzler
Jul30'13at8:06
2
Ihavecreatedapackagethatdoesthisnowandisprobablyeasierandmorerobustthanthisone.PostLink,RepoLink.Hopethishelps!
– WilliamRusnack
May23'17at12:09
5
round_to_n=lambdax,n:xifx==0elseround(x,-int(math.floor(math.log10(abs(x))))+(n-1))protectsagainstx==0andx<0Thankyou@[email protected]'tprotectedagainstundefinedlikemath.inf,orgarbagelikeNoneetc
– AJP
Nov28'19at8:52
|
Show8morecomments
118
%ginstringformattingwillformatafloatroundedtosomenumberofsignificantfigures.Itwillsometimesuse'e'scientificnotation,soconverttheroundedstringbacktoafloatthenthrough%sstringformatting.
>>>'%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'
Share
Follow
answeredAug5'10at4:24
PeterGrahamPeterGraham
10.5k77goldbadges3636silverbadges4141bronzebadges
9
9
TheOP'srequirementwasfor1999tobeformattedas'2000',notas'2000.0'.Ican'tseeatrivialwaytochangeyourmethodtoachievethis.
– TimMartin
Jan14'11at16:04
1
It'sjustwhatIalwayswanted!where'dyoufindthis?
– djhaskin987
Jul19'13at20:34
14
Notethatthebehaviourof%gisnotalwayscorrect.Inparticularitalwaystrimstrailingzeroseveniftheyaresignificant.Thenumber1.23400has6significantdigits,but"%.6g"%(1.23400)willresultin"1.234"whichisincorrect.Moredetailsinthisblogpost:randlet.com/blog/python-significant-figures-format
– randlet
Oct29'13at17:49
3
JustlikethemethodinEvgeny'sanswer,thisfailstocorrectlyround0.075to0.08.Itreturns0.07instead.
– Gabriel
Mar8'16at23:02
2
round_sig=lambdaf,p:float(('%.'+str(p)+'e')%f)allowsyoutoadjustthenumberofsignificantdigits!
– denizb
Aug6'17at22:43
|
Show4morecomments
63
Ifyouwanttohaveotherthan1significantdecimal(otherwisethesameasEvgeny):
>>>frommathimportlog10,floor
>>>defround_sig(x,sig=2):
...returnround(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
Share
Follow
editedMar17'17at16:01
StephenRauch♦
42.9k3030goldbadges9292silverbadges115115bronzebadges
answeredAug5'10at9:49
indgarindgar
63144silverbadges22bronzebadges
8
8
round_sig(-0.0232)->mathdomainerror,youmaywanttoaddanabs()inthere;)
– dgorissen
Dec19'11at14:18
2
JustlikethemethodsinEvgeny'sandPeterGraham'sanswers,thisfailstocorrectlyround0.075to0.08.Itreturns0.07instead.
– Gabriel
Mar8'16at23:05
4
Alsoitfailsforround_sig(0).
– YuvalAtzmon
Feb21'17at11:36
2
@GabrielThatisabuiltin"feature"ofpythonrunningonyourcomputer,andmanifestitselfinitsbehaviorofthefunctionround.docs.python.org/2/tutorial/floatingpoint.html#tut-fp-issues
– NoviceC
May26'17at15:54
2
@GabrielI'veaddedananswerthatexplainswhyyoushouldexpecttoget0.7backfromrounding"0.075"!seestackoverflow.com/a/56974893/1358308
– SamMason
Jul10'19at16:22
|
Show3morecomments
52
f'{float(f"{i:.1g}"):g}'
#OrwithPython<3.6,
'{:g}'.format(float('{:.1g}'.format(i)))
Thissolutionisdifferentfromalloftheothersbecause:
itexactlysolvestheOPquestion
itdoesnotneedanyextrapackage
itdoesnotneedanyuser-definedauxiliaryfunctionormathematicaloperation
Foranarbitrarynumbernofsignificantfigures,youcanuse:
print('{:g}'.format(float('{:.{p}g}'.format(i,p=n))))
Test:
a=[1234,0.12,0.012,0.062,6253,1999,-3.14,0.,-48.01,0.75]
b=['{:g}'.format(float('{:.1g}'.format(i)))foriina]
#b==['1000','0.1','0.01','0.06','6000','2000','-3','0','-50','0.8']
Note:withthissolution,itisnotpossibletoadaptthenumberofsignificantfiguresdynamicallyfromtheinputbecausethereisnostandardwaytodistinguishnumberswithdifferentnumbersoftrailingzeros(3.14==3.1400).Ifyouneedtodoso,thennon-standardfunctionsliketheonesprovidedintheto-precisionpackageareneeded.
Share
Follow
editedApr16'20at14:41
AndyJones
4,18622goldbadges1616silverbadges1919bronzebadges
answeredFeb15'18at17:10
FalkenFalken
64955silverbadges88bronzebadges
9
1
FYI:IfoundthissolutionindependentlyfromeddygeekwhileIwastryingtosolvetheverysameprobleminoneofmycode.NowIrealizethatmysolutionis,obviously,almostidenticaltohis(Ijustnoticedtheerroneousoutputanddidn'tbothertoreadthecode,mymistake).Probablyashortcommentbeneathhisanswerwouldhavebeenenoughinsteadofanewanswer...Theonly(key)differenceisthedoubleuseofthe:gformatterwhichpreserveintegers.
– Falken
Feb15'18at17:32
3
Wow,youranswerneedstobereallyreadfromtoptobottom;)Thisdouble-casttrickisdirty,butneat.(Notethat1999formattedas2000.0suggests5significantdigits,soithastogothrough{:g}again.)Ingeneral,integerswithtrailingzerosareambiguouswithregardtosignificantfigures,unlesssometechnique(likeoverlineabovelastsignificant)isused.
– TomaszGandor
Apr6'20at6:45
1
Doyoumindtojustwalkmethroughhowthisworks?Whatare:.1gand:gIdontthinkivecomeacrosseitherbefore,andhaventfoundanythinginthedocseither
– E-A
Oct12'20at9:40
3
Forsomereason,thissolutionfailsforlongerprecisions.'{:g}'.format(float('{:.{p}g}'.format(0.123456789012,p=20)))resultsin0.123457.
– TomSwirly
Apr8at9:42
2
@TomSwirlyThereasonwhyyouaregettingamaximumprecisionof6isforthefirst'{:g}'(basedonthedocumentation:"Withnoprecisiongiven,usesaprecisionof6significantdigits").Ifyoupasstheprecisioninthat'{:g}'too,youwillgetthecorrectresult.Thecodewouldbe:'{:.{p}g}'.format(float('{:.{p}g}'.format(0.123456789012,p=12)),p=12)resultingin0.123456789012
– lscena
Jul27at20:37
|
Show4morecomments
11
Ihavecreatedthepackageto-precisionthatdoeswhatyouwant.Itallowsyoutogiveyournumbersmoreorlesssignificantfigures.
Italsooutputsstandard,scientific,andengineeringnotationwithaspecifiednumberofsignificantfigures.
Intheacceptedanswerthereistheline
>>>round_to_1(1234243)
1000000.0
Thatactuallyspecifies8sigfigs.Forthenumber1234243mylibraryonlydisplaysonesignificantfigure:
>>>fromto_precisionimportto_precision
>>>to_precision(1234243,1,'std')
'1000000'
>>>to_precision(1234243,1,'sci')
'1e6'
>>>to_precision(1234243,1,'eng')
'1e6'
Itwillalsoroundthelastsignificantfigureandcanautomaticallychoosewhatnotationtouseifanotationisn'tspecified:
>>>to_precision(599,2)
'600'
>>>to_precision(1164,2)
'1.2e3'
Share
Follow
editedJul29'18at23:45
offby1
5,9422727silverbadges4444bronzebadges
answeredMay23'17at11:59
WilliamRusnackWilliamRusnack
75877silverbadges1313bronzebadges
7
NowI'mlookingforthesamebutappliedtoapandasdf
– mhoff
Jan25'19at11:29
@mhoffyoucanprobablyusepandasmapwithalambda.lambdax:to_precision(x,2)
– WilliamRusnack
Feb7'19at19:44
Addthisto(PyPI)[pypi.org/].Thereisnothinglikethisthatexistsonthere,asfarasIcantell.
– Morgoth
Jul29'19at11:55
thisisagreatpackagebutIthinkmostofthefeaturesarenowinthesigfigmodule
– HyperActive
Nov30'19at17:32
2
ithasabug:std_notation(9.999999999999999e-05,3)gives:'0.00010'whichisonly2significantdigits
– BorisMulder
Mar31'20at11:58
|
Show2morecomments
11
Todirectlyanswerthequestion,here'smyversionusingnamingfromtheRfunction:
importmath
defsignif(x,digits=6):
ifx==0ornotmath.isfinite(x):
returnx
digits-=math.ceil(math.log10(abs(x)))
returnround(x,digits)
Mymainreasonforpostingthisanswerarethecommentscomplainingthat"0.075"roundsto0.07ratherthan0.08.Thisisdue,aspointedoutby"NoviceC",toacombinationoffloatingpointarithmetichavingbothfiniteprecisionandabase-2representation.Thenearestnumberto0.075thatcanactuallyberepresentedisslightlysmaller,henceroundingcomesoutdifferentlythanyoumightnaivelyexpect.
Alsonotethatthisappliestoanyuseofnon-decimalfloatingpointarithmetic,e.g.CandJavabothhavethesameissue.
Toshowinmoredetail,weaskPythontoformatthenumberin"hex"format:
0.075.hex()
whichgivesus:0x1.3333333333333p-4.Thereasonfordoingthisisthatthenormaldecimalrepresentationofteninvolvesroundingandhenceisnothowthecomputeractually"sees"thenumber.Ifyou'renotusedtothisformat,acoupleofusefulreferencesarethePythondocsandtheCstandard.
Toshowhowthesenumbersworkabit,wecangetbacktoourstartingpointbydoing:
0x13333333333333/16**13*2**-4
whichshouldshouldprintout0.075.16**13isbecausethereare13hexadecimaldigitsafterthedecimalpoint,and2**-4isbecausehexexponentsarebase-2.
Nowwehavesomeideaofhowfloatsarerepresentedwecanusethedecimalmoduletogiveussomemoreprecision,showinguswhat'sgoingon:
fromdecimalimportDecimal
Decimal(0x13333333333333)/16**13/2**4
giving:0.07499999999999999722444243844andhopefullyexplainingwhyround(0.075,2)evaluatesto0.07
Share
Follow
editedJul10'19at16:37
answeredJul10'19at16:21
SamMasonSamMason
12.2k11goldbadge3232silverbadges4646bronzebadges
6
3
Thisisagreatexplanationofwhy0.075isroundeddownto0.07atthecodelevel,butwe(inthephysicalsciences)havebeentaughttoalwaysroundupnotdown.Sotheexpectedbehaviourisactuallytohave0.08asaresult,floatingpointprecisionissuesnotwithstanding.
– Gabriel
Jul10'19at18:25
1
I'munsurewhereyourconfusionis:whenyouenter0.075you'reactuallyentering~0.07499(asabove),whichroundsaccordingtonormalmathsrules.ifyouwereusingadatatype(likedecimalfloatingpoint)thatcouldrepresent0.075thenitshouldindeedroundto0.08
– SamMason
Jul10'19at20:12
2
I'mnotconfused.WhenIenter0.075I'mactuallyentering0.075.WhateverhappensinthefloatingpointmathinsidethecodeIdon'tcare.
– Gabriel
Jul10'19at20:49
@Gabriel:Andifyouhaddeliberatelyentered0.074999999999999999,whatwouldyouexpecttogetinthatcase?
– MarkDickinson
Jul11'19at17:06
1
@MarkDickinsonthatdepends.Onesignificantfigure:0.07,two:0.075.
– Gabriel
Jul11'19at18:43
|
Show1morecomment
5
Toroundanintegerto1significantfigurethebasicideaistoconvertittoafloatingpointwith1digitbeforethepointandroundthat,thenconvertitbacktoitsoriginalintegersize.
Todothisweneedtoknowthelargestpowerof10lessthantheinteger.Wecanusefloorofthelog10functionforthis.
frommathimportlog10,floor
defround_int(i,places):
ifi==0:
return0
isign=i/abs(i)
i=abs(i)
ifi<1:
return0
max10exp=floor(log10(i))
ifmax10exp+1>>round(1.2322,2)
1.23
Integersaretrickier.They'renotstoredasbase10inmemory,sosignificantplacesisn'tanaturalthingtodo.It'sfairlytrivialtoimplementoncethey'reastringthough.
Orforintegers:
>>>defintround(n,sigfigs):
...n=str(n)
...returnn[:sigfigs]+('0'*(len(n)-(sigfigs)))
>>>intround(1234,1)
'1000'
>>>intround(1234,2)
Ifyouwouldliketocreateafunctionthathandlesanynumber,mypreferencewouldbetoconvertthembothtostringsandlookforadecimalplacetodecidewhattodo:
>>>defroundall1(n,sigfigs):
...n=str(n)
...try:
...sigfigs=n.index('.')
...exceptValueError:
...pass
...returnintround(n,sigfigs)
Anotheroptionistocheckfortype.Thiswillbefarlessflexible,andwillprobablynotplaynicelywithothernumberssuchasDecimalobjects:
>>>defroundall2(n,sigfigs):
...iftype(n)isint:returnintround(n,sigfigs)
...else:returnround(n,sigfigs)
Share
Follow
editedAug5'10at2:28
answeredAug5'10at1:35
TimMcNamaraTimMcNamara
17.2k33goldbadges5050silverbadges7878bronzebadges
2
Justmessingwithstringswon'troundthenumbers.1999roundedto1significantfigureis2000,not1000.
– PeterGraham
Aug5'10at2:43
ThereisagooddiscussionofthisproblemarchivedatActiveStatecode.activestate.com/lists/python-tutor/70739
– TimMcNamara
Aug5'10at2:54
Addacomment
|
3
Ifyouwanttoroundwithoutinvolvingstrings,thelinkIfoundburiedinthecommentsabove:
http://code.activestate.com/lists/python-tutor/70739/
strikesmeasbest.Thenwhenyouprintwithanystringformattingdescriptors,yougetareasonableoutput,andyoucanusethenumericrepresentationforothercalculationpurposes.
Thecodeatthelinkisathreeliner:def,doc,andreturn.Ithasabug:youneedtocheckforexplodinglogarithms.Thatiseasy.Comparetheinputtosys.float_info.min.Thecompletesolutionis:
importsys,math
deftidy(x,n):
"""Return'x'roundedto'n'significantdigits."""
y=abs(x)
ify<=sys.float_info.min:return0.0
returnround(x,int(n-math.ceil(math.log10(y))))
Itworksforanyscalarnumericvalue,andncanbeafloatifyouneedtoshifttheresponseforsomereason.Youcanactuallypushthelimitto:
sys.float_info.min*sys.float_info.epsilon
withoutprovokinganerror,ifforsomereasonyouareworkingwithminisculevalues.
Share
Follow
answeredApr13'18at6:49
getting_sleepygetting_sleepy
3111bronzebadge
Addacomment
|
3
Thepostedanswerwasthebestavailablewhengiven,butithasanumberoflimitationsanddoesnotproducetechnicallycorrectsignificantfigures.
numpy.format_float_positionalsupportsthedesiredbehaviourdirectly.Thefollowingfragmentreturnsthefloatxformattedto4significantfigures,withscientificnotationsuppressed.
importnumpyasnp
x=12345.6
np.format_float_positional(x,precision=4,unique=False,fractional=False,trim='k')
>12340.
Share
Follow
answeredOct21'19at17:01
AutumnAutumn
2,1581515silverbadges3030bronzebadges
1
Thedocumentation(movedtonumpy.org/doc/stable/reference/generated/…)statesthatthisfunctionimplementstheDragon4algorithm(ofSteele&White1990,dl.acm.org/doi/pdf/10.1145/93542.93559).Itproducesannoyingresults,e.g.print(*[''.join([np.format_float_positional(.01*a*n,precision=2,unique=False,fractional=False,trim='k',pad_right=5)forain[.99,.999,1.001]])fornin[8,9,10,11,12,19,20,21]],sep='\n').Ididn'tcheckDragon4itself.
– Rainald62
May12'20at15:09
Addacomment
|
2
Thesigfigpackage/librarycoversthis.Afterinstallingyoucandothefollowing:
>>>fromsigfigimportround
>>>round(1234,1)
1000
>>>round(0.12,1)
0.1
>>>round(0.012,1)
0.01
>>>round(0.062,1)
0.06
>>>round(6253,1)
6000
>>>round(1999,1)
2000
Share
Follow
answeredNov30'19at17:32
HyperActiveHyperActive
70877silverbadges1111bronzebadges
Addacomment
|
1
Usingpython2.6+new-styleformatting(as%-styleisdeprecated):
>>>"{0}".format(float("{0:.1g}".format(1216)))
'1000.0'
>>>"{0}".format(float("{0:.1g}".format(0.00356)))
'0.004'
Inpython2.7+youcanomittheleading0s.
Share
Follow
answeredJan8'18at13:34
eddygeekeddygeek
3,58622goldbadges2121silverbadges2929bronzebadges
2
Withwhatversionofpython?Python3.6.3|Anaconda,Inc.|(default,Oct132017,12:02:49)hasthesameoldroundingproblem."{0}".format(float("{0:.1g}".format(0.075)))yields'0.07',not'0.08'
– DonMclachlan
Feb22'19at19:00
@DonMclachlanI'veaddedanexplanationofwhythisisexpectedinstackoverflow.com/a/56974893/1358308
– SamMason
Jul10'19at16:24
Addacomment
|
0
IranintothisaswellbutIneededcontrolovertheroundingtype.Thus,Iwroteaquickfunction(seecodebelow)thatcantakevalue,roundingtype,anddesiredsignificantdigitsintoaccount.
importdecimal
frommathimportlog10,floor
defmyrounding(value,roundstyle='ROUND_HALF_UP',sig=3):
roundstyles=['ROUND_05UP','ROUND_DOWN','ROUND_HALF_DOWN','ROUND_HALF_UP','ROUND_CEILING','ROUND_FLOOR','ROUND_HALF_EVEN','ROUND_UP']
power=-1*floor(log10(abs(value)))
value='{0:f}'.format(value)#formatvaluetostringtopreventfloatconversionissues
divided=Decimal(value)*(Decimal('10.0')**power)
roundto=Decimal('10.0')**(-sig+1)
ifroundstylenotinroundstyles:
print('roundstylemustbeinlist:',roundstyles)##Couldthrownanexceptionhereifyouwant.
return_val=decimal.Decimal(divided).quantize(roundto,rounding=roundstyle)*(decimal.Decimal(10.0)**-power)
nozero=('{0:f}'.format(return_val)).rstrip('0').rstrip('.')#stripsouttrailing0and.
returndecimal.Decimal(nozero)
forxinlist(map(float,'-1.2341.23450.03-90.2590.345439123.3111'.split())):
print(x,'roundedUP:',myrounding(x,'ROUND_UP',3))
print(x,'roundednormal:',myrounding(x,sig=3))
Share
Follow
editedSep28'17at17:00
MiriamFarber
16.9k1212goldbadges5353silverbadges7272bronzebadges
answeredSep28'17at16:52
drew.raydrew.ray
2111silverbadge33bronzebadges
Addacomment
|
0
Thisfunctiondoesanormalroundifthenumberisbiggerthan10**(-decimal_positions),otherwiseaddsmoredecimaluntilthenumberofmeaningfuldecimalpositionsisreached:
defsmart_round(x,decimal_positions):
dp=-int(math.log10(abs(x)))ifx!=0.0elseint(0)
returnround(float(x),decimal_positions+dpifdp>0elsedecimal_positions)
Hopeithelps.
Share
Follow
editedJul19'18at11:50
answeredJul19'18at9:38
EttoreGalliEttoreGalli
59344silverbadges2020bronzebadges
Addacomment
|
0
https://stackoverflow.com/users/1391441/gabriel,doesthefollowingaddressyourconcernaboutrnd(.075,1)?
Caveat:returnsvalueasafloat
defround_to_n(x,n):
fmt='{:1.'+str(n)+'e}'#gives1.nfigures
p=fmt.format(x).split('e')#getmantissaandexponent
#round"extra"figureoffmantissa
p[0]=str(round(float(p[0])*10**(n-1))/10**(n-1))
returnfloat(p[0]+'e'+p[1])#convertstrtofloat
>>>round_to_n(750,2)
750.0
>>>round_to_n(750,1)
800.0
>>>round_to_n(.0750,2)
0.075
>>>round_to_n(.0750,1)
0.08
>>>math.pi
3.141592653589793
>>>round_to_n(math.pi,7)
3.141593
Share
Follow
editedFeb22'19at19:32
answeredFeb22'19at18:46
DonMclachlanDonMclachlan
40144silverbadges88bronzebadges
Addacomment
|
0
Thisreturnsastring,sothatresultswithoutfractionalparts,andsmallvalueswhichwouldotherwiseappearinEnotationareshowncorrectly:
defsigfig(x,num_sigfig):
num_decplace=num_sigfig-int(math.floor(math.log10(abs(x))))-1
return'%.*f'%(num_decplace,round(x,num_decplace))
Share
Follow
answeredMar15'19at12:04
GnubieGnubie
2,50744goldbadges2424silverbadges3636bronzebadges
Addacomment
|
0
Givenaquestionsothoroughlyansweredwhynotaddanother
Thissuitsmyaestheticalittlebetter,thoughmanyoftheabovearecomparable
importnumpyasnp
number=-456.789
significantFigures=4
roundingFactor=significantFigures-int(np.floor(np.log10(np.abs(number))))-1
rounded=np.round(number,roundingFactor)
string=rounded.astype(str)
print(string)
Thisworksforindividualnumbersandnumpyarrays,andshouldfunctionfinefornegativenumbers.
There'soneadditionalstepwemightadd-np.round()returnsadecimalnumberevenifroundedisaninteger(i.e.forsignificantFigures=2wemightexpecttogetback-460butinsteadweget-460.0).Wecanaddthissteptocorrectforthat:
ifroundingFactor<=0:
rounded=rounded.astype(int)
Unfortunately,thisfinalstepwon'tworkforanarrayofnumbers-I'llleavethattoyoudearreadertofigureoutifyouneed.
Share
Follow
answeredAug3'19at8:59
zephyrzephyr
21522silverbadges1313bronzebadges
Addacomment
|
0
importmath
defsig_dig(x,n_sig_dig):
num_of_digits=len(str(x).replace(".",""))
ifn_sig_dig>=num_of_digits:
returnx
n=math.floor(math.log10(x)+1-n_sig_dig)
result=round(10**-n*x)*10**n
returnfloat(str(result)[:n_sig_dig+1])
>>>sig_dig(1234243,3)
>>>sig_dig(243.3576,5)
1230.0
243.36
Share
Follow
editedMar27'20at17:37
answeredMar26'20at21:29
LetzerWilleLetzerWille
4,55433goldbadges1919silverbadges2424bronzebadges
4
1
Thisfunctionisnotdoingwhatitshould.sig_dig(1234243,3)shouldbe1230000andnot1230.0.
– timmey
Nov6'20at12:38
Ifyoujustreturntheresult,thenitwillbefine(i.e.removethelastlineofyourfunction).
– timmey
Nov6'20at12:47
Also,youshouldtaketheabsolutevaluemath.log10(abs(x))todealwithnegativenumbers.Giventhetwocorrections,itlookslikeitworkswellandisquitefast.
– timmey
Nov6'20at13:21
It'sunlikelyit'sfast,becauseitusesmath.log10
– TomSwirly
Jul29at8:14
Addacomment
|
0
Mostoftheseanswersinvolvethemath,decimaland/ornumpyimportsoroutputvaluesasstrings.Hereisasimplesolutioninbasepythonthathandlesbothlargeandsmallnumbersandoutputsafloat:
defsig_fig_round(number,digits=3):
power="{:e}".format(number).split('e')[1]
returnround(number,-(int(power)-digits))
Share
Follow
answeredDec16'20at18:23
JoshDuranJoshDuran
1122bronzebadges
Addacomment
|
0
Asimplevariantusingthestandarddecimallibrary
fromdecimalimportDecimal
defto_significant_figures(v:float,n_figures:int)->str:
d=Decimal(v)
d=d.quantize(Decimal((0,(),d.adjusted()-n_figures+1)))
returnstr(d.quantize(Decimal(1))ifd==d.to_integral()elsed.normalize())
Testingit
>>>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'
Share
Follow
answeredSep4at21:47
IgorMikushkinIgorMikushkin
1,0091313silverbadges1919bronzebadges
Addacomment
|
0
Thisfunctiontakesbothpositiveandnegativenumbersanddoesthepropersignificantdigitrounding.
frommathimportfloor
defsignificant_arithmetic_rounding(n,d):
'''
Thisfunctiontakesafloatingpointnumberandtheno.ofsignificantdigitd,performsignificantdigits
arithmeticroundingandreturnsthefloatingpointnumberafterrounding
'''
ifn==0:
return0
else:
#Checkingwhethertheno.isnegativeorpositive.Ifitisnegativewewilltaketheabsolutevalueofitandproceed
neg_flag=0
ifn<0:
neg_flag=1
n=abs(n)
n1=n
#Countingtheno.ofdigitstotheleftofthedecimalpointintheno.
ld=0
while(n1>=1):
n1/=10
ld+=1
n1=n
#Countingtheno.ofzerostotherightofthedecimalpointandbeforethefirstsignificantdigitintheno.
z=0
ifld==0:
while(n1<=0.1):
n1*=10
z+=1
n1=n
#No.ofdigitstobeconsideredafterdecimalforrounding
rd=(d-ld)+z
n1*=10**rd
#Increaseby0.5andtakethefloorvalueforrounding
n1=floor(n1+0.5)
#Placingthedecimalpointatproperposition
n1/=10**rd
#Iftheoriginalnumberisnegativethenmakeitnegative
ifneg_flag==1:
n1=0-n1
returnn1
Testing:
>>>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
Share
Follow
editedDec7at18:29
answeredDec7at15:08
AyanDeAyanDe
111bronzebadge
Newcontributor
AyanDeisanewcontributortothissite.Takecareinaskingforclarification,commenting,andanswering.
CheckoutourCodeofConduct.
Addacomment
|
YourAnswer
ThanksforcontributingananswertoStackOverflow!Pleasebesuretoanswerthequestion.Providedetailsandshareyourresearch!Butavoid…Askingforhelp,clarification,orrespondingtootheranswers.Makingstatementsbasedonopinion;backthemupwithreferencesorpersonalexperience.Tolearnmore,seeourtipsonwritinggreatanswers.
Draftsaved
Draftdiscarded
Signuporlogin
SignupusingGoogle
SignupusingFacebook
SignupusingEmailandPassword
Submit
Postasaguest
Name
Email
Required,butnevershown
PostYourAnswer
Discard
Byclicking“PostYourAnswer”,youagreetoourtermsofservice,privacypolicyandcookiepolicy
Nottheansweryou'relookingfor?Browseotherquestionstaggedpythonmathroundingsignificant-digitsoraskyourownquestion.
TheOverflowBlog
Smashingbugstosetaworldrecord:AWSBugBust
Podcast399:ZerotoMVPwithoutprovisioningadatabase
FeaturedonMeta
Reducingtheweightofourfooter
NewresponsiveActivitypage
Communityinputneeded:Therulesforcollectivesarticles
A/BtestingontheAskpage
Linked
2
Roundnumberwithvariablepowertotwodigitsaccuracy
2
Howtofloornumberstowholenumberinpython
-3
Roundtotwoplaces(notdecimalplaces)python
0
Pythonround-Twodecidingdecimals
0
ExponentialtoFloat(GettingALLdecimalnumbersofFloat)
1
Howtostringformatafloattothe10sor100splace?
0
Formattingfloatssotheyallhavethesametotaldigits(ex1.234,456.7)
0
Printingto3significantfiguresinpython
-1
Roundanumbertoaspecificnumberofsigfigspython
3494
Isfloatingpointmathbroken?
Seemorelinkedquestions
Related
6032
HowdoImergetwodictionariesinasingleexpression(takeunionofdictionaries)?
6448
HowdoIcheckwhetherafileexistswithoutexceptions?
6494
WhataremetaclassesinPython?
1386
HowtoroundanumbertondecimalplacesinJava
5022
HowcanIsafelycreateanesteddirectoryinPython?
2714
HowdoyouchangethesizeoffiguresdrawnwithMatplotlib?
7077
DoesPythonhaveaternaryconditionaloperator?
3418
HowtogetthecurrenttimeinPython
3156
HowdoIconcatenatetwolistsinPython?
3441
Howtoroundtoatmost2decimalplaces,ifnecessary?
HotNetworkQuestions
Whattypesofenemieswouldatwo-handedsledgehammerbeusefulagainstinamedievalfantasysetting?
Isthereawordorphrasethatdescribesoldarticlespublishedagain?
AfterourfirstZoominterview,mypotentialsupervisoraskedmetoprepareapresentationforthenextZoommeeting
WhatwastheBigBangmodeloriginallycalled?
Howtoreplaceabrokenfronthubonavintagesteelwheelfromavintagesteelbike?
Isubmittedapaperoverayearagoandhavenotheardback.WhatshouldIdo?
Authorshipofastudentwhopublishedseparatelywithoutpermission
DoIholdthecopyrightontestanswers?
AoCG2021Day13:Defraginaction!
Log-linearandGLM(Poisson)regression
WhattoavoidwhenwritingdistantandinconsequentialPOVs?
What'sthemeaningof"Manweißhaltgefühltnichts"?
Whyusediamond-likecarboninsteadofdiamond?
Whydoesthisnewdirectoryhavealinkcountof3?
DidYosef'schildreninheritanyoftherichesthatYosefaccumulatedasaVizierofEgypt?
MeasuringACwithaDCoffsetusingadigitalmulti-meter
PredictingwithaGLM
555Astable:Separatechargeanddischargeresistors?
WheredoestheextraspacecomefromafteracapitalPinmathmode?
Shouldoneadjustp-valuesformultipletestingcorrectionsinresearch?
Whathappenstoafamiliarifthemasterdiesandisbroughtback?
What'sthedifferencebetween«fonctionner»and«sefonctionner»?
Residentialfiberroughin?
mixedintegerprogrammingwithifthenstatementfortwobinarysequences
morehotquestions
Questionfeed
SubscribetoRSS
Questionfeed
TosubscribetothisRSSfeed,copyandpastethisURLintoyourRSSreader.
lang-py
Yourprivacy
Byclicking“Acceptallcookies”,youagreeStackExchangecanstorecookiesonyourdeviceanddiscloseinformationinaccordancewithourCookiePolicy.
Acceptallcookies
Customizesettings