Calculate a number to the power of a large integer - python

I'm trying to help someone calculate the value of 4^3e9.
The problem is that most software don't support numbers this large. Is there an alternative way to calculate this?
My first attempt is to try to divide the number as it is being calculated by looping from 1 to 3e9. If the intermediate result is > 10 then I divide it by it's power of 10, then add this to a variable. In the end I will have a floating point number and the power of 10.
import math
powerof10 = 0
powerof = int(3e9)
# print('powerof', powerof)
initial_value = 4
float_value = initial_value
for i in range(1,powerof): #start from 1 to get correct number of operations
float_value *= initial_value
# print('float value', float_value)
print(i)
if (float_value > 10):
powerof10increment = math.floor(math.log10(float_value))
# print('powerof10', powerof10increment)
powerof10 += powerof10increment
float_value /= 10**powerof10increment
# print('reduced float value', float_value)
print(float_value, ' x 10^', powerof10)
This based on this question here: I want to know what is the value of 4 to the power of 3000000000 (3e+9)
According to the question the number should be in the format 1 x 10^x, so I think only x is required.

Thanks to #NickODell for his comment!
import math
powerof10 = (3e9)*math.log(4)/math.log(10)
print(powerof10)
significand = 10**(powerof10 - math.floor(powerof10))
print(significand, 'x 10^', math.floor(powerof10))
# 9.63578180503111 x 10^ 1806179973
Which matches with the result I get from Wolfram Alpha.

Related

Python: How to round numbers smaller than 1 adaptively with specified precision?

I usually use
x = round(x, 3)
to round a number to the precision of 3 digits. Now I have this array:
[-1.10882605e-04 -2.01874994e-05 3.24209095e-05 -1.56917988e-05
-4.61406358e-05 1.99080610e-05 7.04079594e-05 2.64600122e-05
-3.53022316e-05 1.50542793e-05]
And using the same code just flattens everything down to 0. What I would like to have though is a function that gives me the most significant 3 digits rounded like it usually works for numbers larger than 1. Like this:
special_round(0.00034567, 3)
=
0.000346
Any idea how this could be done? Thanks!
Here is a solution that figures out the order of magnitude and does an elment wise rounding.
Note that this will only work correctly for values < 1 and > -1, which I guess is a valid assumption regarding your example data.
import numpy as np
a = np.array([-1.10882605e-04, -2.01874994e-05, 3.24209095e-05, -1.56917988e-05,
-4.61406358e-05, 1.99080610e-05, 7.04079594e-05 , 2.64600122e-05,
-3.53022316e-05 , 1.50542793e-05])
def special_round(vec):
exponents = np.floor(np.log10(np.abs(vec))).astype(int)
return np.stack([np.round(v, decimals=-e+3) for v, e in zip(vec, exponents)])
b = special_round(a)
>>> array([-1.109e-04, -2.019e-05, 3.242e-05, -1.569e-05, -4.614e-05,
1.991e-05, 7.041e-05, 2.646e-05, -3.530e-05, 1.505e-05])
Problem is, numbers you provided are starting to be so small that you are approaching limit of floating point precision, thus some artifacts show up seemingly for no reason.
def special_round(number, precision):
negative = number < 0
number = abs(number)
i = 0
while number <= 1 or number >= 10:
if number <= 1:
i += 1
number *= 10
else:
i += -1
number /= 10
rounded = round(number, precision)
if negative:
rounded = -rounded
return rounded * (10 ** -i)
Output:
[-0.0001109, -2.019e-05, 3.2420000000000005e-05, -1.569e-05, -4.614e-05, 1.9910000000000004e-05, 7.041000000000001e-05, 2.646e-05, -3.5300000000000004e-05, 1.505e-05]
You can do so by creating a specific function using the math package:
from math import log10 , floor
import numpy as np
def round_it(x, sig):
return round(x, sig-int(floor(log10(abs(x))))-1)
a = np.array([-1.10882605e-04, -2.01874994e-05, 3.24209095e-05, -1.56917988e-05,
-4.61406358e-05, 1.99080610e-05, 7.04079594e-05, 2.64600122e-05,
-3.53022316e-05, 1.50542793e-05])
round_it_np = np.vectorize(round_it) # vectorize the function to apply on numpy array
round_it_np(a, 3) # 3 is rounding with 3 significant digits
This will result in
array([-1.11e-04, -2.02e-05, 3.24e-05, -1.57e-05, -4.61e-05, 1.99e-05,
7.04e-05, 2.65e-05, -3.53e-05, 1.51e-05])
Here is a solution:
from math import log10, ceil
def special_round(x, n) :
lx = log10(abs(x))
if lx >= 0 : return round(x, n)
return round(x, n-ceil(lx))
for x in [10.23456, 1.23456, 0.23456, 0.023456, 0.0023456] :
print (x, special_round(x, 3))
print (-x, special_round(-x, 3))
Output:
10.23456 10.235
-10.23456 -10.235
1.23456 1.235
-1.23456 -1.235
0.23456 0.235
-0.23456 -0.235
0.023456 0.0235
-0.023456 -0.0235
0.0023456 0.00235
-0.0023456 -0.00235
You can use the common logarithm (provided by the built-in math module) to calculate the position of the first significant digit in your number (with 2 representing the hundreds, 1 representing the tens, 0 representing the ones, -1 representing the 0.x, -2 representing the 0.0x and so on...). Knowing the position of the first significant digit, you can use it to properly round the number.
import math
def special_round(n, significant_digits=0):
first_significant_digit = math.ceil((math.log10(abs(n))))
round_digits = significant_digits - first_significant_digit
return round(n, round_digits)
>>> special_round(0.00034567, 3)
>>> 0.000346

Python OverflowError: int too large to convert to float

I have a number and I want to find the sum of all of its possible substrings. Since the sum may be very large, I am taking modulo 1e9+7. Here is the code I wrote for it:
n = input()
total = 0
for i in range(len(n)):
for j in range(i, len(n)):
total = (total + int(n[i:j+1]))%(1e9+7)
print(int(total))
But this gives me Overflow error:
OverflowError: int too large to convert to float
Taking modulo inside also doesn't help:
total = (total%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7)
Neither does converting total to int every step:
total = int((total%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7))
I searched online, and many people were using decimal, so I tried that too:
import decimal
n = input()
total = 0
for i in range(len(n)):
for j in range(i, len(n)):
total = decimal.Decimal((int(total)%(1e9+7) + int(n[i:j+1])%(1e9+7))%(1e9+7))
print(int(total))
This also gave me the same error. So how can I fix it?
EDIT:
This is the input value causing the error:
630078954945407486971302572117011329116721271139829179349572383637541443562605787816061110360853600744212572072073871985233228681677019488795915592613136558538697419369158961413804139004860949683711756764106408843746324318507090165961373116110504156510362261390086415758369311946617855091322330974469225379475157034653986221430086928768825350265642050874148148762850633380318092218497923938934331494944977897218250062378381926065651168047990017214673422724320097123140849040864223795967322521445859865961967502883479331506850337535224430391571038073324911164139663006137417510539192705821435391823658411385338369730232377028300695738866310468334377735439392551346134885024889217010755804062396901380184592416137322133531990680941959600864409332647120219490414701983979339375751465609840801484592889925172867105767663865003474673877306782492180067353856493873352082672833242368295700361941406607094298524971010582848155295175876416280789802070376313832361148791530700602039387918303750966965311391574707837728570176384970704855124594407172251268098706978376090542912929344492513384183231040016207412648019561891411057151352984928184115181483534959666911309714744265773932487092170761893895469807486999330039447615795396834925983574737750806569360090695009597077440117397176004125384806886783639660621550162794222825503301866755919064102371025428970202609474167093725973377029019369542489008907399816344268271107251422642444394295031677496626574918192538987307032199141725692286015261369012945174380684144484086524852886270717368426832490990772158458075266904766542991903970407465284703623099975166486775916952691073355877964592340230731529088307662462168730966089062336436389277513929792989509527961806655782453847736236387259057358913693838332016851781407524359352813229072505380650711693049176679191021591021389372641247384964875287336650708846120446276882272810745622693709331578317206645848042706067557480758511553310824640020649394355322305550804086562784060919544289531008318716584762468479626254129440271062831239695632816441075920969278753806765451632278698182308325313693381046301850639648800754286747096420253430423489479466804681482044272737999450499555465823164480037422222367329404142745283822947899313540404366082279717101515216147594766392292429511243594117952923319141560834706050302935730124475680758933436231491685270482951411606790235850929380027076481544634203449136248177171198738003486838372217932769689898884784243826855286091288358239337707121625402050851090825870703676300673135330647766969648618275025084598123309185991065848687389917566591933063673989563554382295252021136544002390268843474613430643976640252484632736275857290476774458675146529714463940660919706163233969511685041545624837717646981487338708223589261847530514133271116906741091917303278220653192405195999010112864383206483703165777476499412818478890639921457227974733696980927826881905040085772367856544559431242332068267736163848514181227641896012840513431718789320462329400102516689122316306450427759800832003864806238880726778463445628851437837462460535312158694258263309302240517780411649608046974426356882853543894970861987774349994574781336617336532821610244134603281437218963727001383319023603953398010028490193243704729281796345148350290421966348930850029874490245386530847693496493617805444480239004190850309960252932678216332242871877009997232445612436261407704091991812835292853218055207198699990193596327522065871513324383404436885617489886675946278629169614212976734843602198938090909080423822416990482891694415707626880182335127385564845496968722502531064508236794490149037021373756875425278069621745860863912399196641388414399463171257761192133719058891540419926061937259684055960761838199081600923840918336924120526335236516500115108241855287430263809480233364084000105646409638910878994420820422552248809062853062971314598633808334114010418924133364933998209352785219452456089337721022144079478199256501302345218342858278235244199769192326879823000937772497828914123378185067698603690831733524939588396025784744225418501083799649691393873269892335315415985069239360869306287430161725433942167215211261881754762154607113521244775811112287675881463204557903372983296624502192459971356246676084633217778109344434581417296897250881570580436981350693342923679859228288541131389540894299576663507525370715066110292813780358628483132303131742983176445700582642966318721896316623598268218673189722517718549132701529540520838922283977941956346618584749724827265852568855500361230814706488134611068845316354598799199730845206624628172917488457386459633185969341459672532379007964850480186110477536989316248137632870890622881765455399233258931339410494872048786445380805620853716965362789859403153144908183575383939310217279705139721560019568071214255994974408572648841828625948484183872232281767754936910627565103682925375742419024815987856586166378115801243175559269046804610268271061187624472308223805466602642940260042682812756256714586960165383407898099487002894444062178839391272002262993374941547876859908138330758067507911277955632733866611899695647351688393078353839611712871637384462404921878353336617815170011477929312619557000783485114417555469412886951873941491122663330089140640237525839190435611147175201365580352057169422983019756479705286311737745688878300295162035783336721495176173005235943366036579342403031858371914608154767616552994518813852963325330926988565056420401996182426971074864830358200261362270644352471067742908740066312532706251619727693803689605359722994531913085746256816708333207607372464782479204187957800323115042281681129259667352353517828344865153265302260116463924808962369896134974192415072584064052318417051648079212739917316031264326241507504548923934897411859282836187869534528811502263549599774513219264816628970416773822011462914052436110107140947441642811202817152783793620844688755256396789417685977459433814911438287855016776285922198699082347185992693560300125534315526770599208589855117129892234808497648798749646357191091546146105862763759843591202631705539149848234511495065117372464217143148171544816412125072538951795020039403886647971400954941112844849901590156966236341935249533139330401618307950786879596469984119359421473188358955907773883294422386655263220117627516995224969119904423765978663514224958566699689223512229385859291888846405683717180332460248187496572144703276206259527743572333980326718238070708650626983118629971542697495485252436024567421318695854715454101364076644687730899594195633275321940815295981062932643316855398782785214003121345721054960499469768201901436790482699005065113381322434770359397558788285726356480844311358408385253074776523383477020175018046561198787369898157059096899613482593561519419424142071652533171543891165116251895092189352681035517633166882961672980048326420273966474172389658068362117989909317156664012999905834065753973024952538940459359134550258647169854000824881036941617642608336413135147747841565829503975928572807411306180458140011310004983383026486015252188390643855363612216856777424655584758055581172316113883725410980557553123430983725023598059269514271705141359723255705532679522179269076133226643135890378252461618715340762528062563692617084267038794880235151507089462270896512581989114649911930878095396167316626567923044257435256806444296060636631937672317042925789128926010875180848009703217786800815516725253240060242786574356358801695111745961187387934689215227487920216703113061886444488110070984015605138767865701169972101412815405111287993463590619141283476936740880771219789950164205754467253452729863863950188739206664510955140236732140158021974750113109733958553067094099406873014624519007182600409029981781192576220342072442404407525694905182026252480724976436388060662190514332680872481044874701969108472815273272711817597987293115253454183720993206057768497928765003643915107639254922781596562385649150660525460064354624202531015121109364122338886448890343464196409635269404582149158284742251021906623863213747664602076214326636400706220794772134432273627481233425177349936452817255847706031575002057972719912748242114947097609007914285108694438842246267149271162583225184547641087826552789896176698128504268589381137327318145707839809327397245651593444250042725815049799745201372918555659842435159140214766015206264721726961406530774240071612440812084893955728905341340722978959370951469131953687044216423231488696742678073353379700564119257217803190999447776766945656573316206535726981650249163828677908520393197985243387213795555465230391800618144495416908755212757986378350464035578468435976351162791656892497974733578066603931101486067508297960437234016531761812630581332141184120753306673976159208563797007731706257116416221162110419311205495221132895418746168121064205944498701002545540456478596919625174145565742316551390140063146675199648332585331762709727331999408582325796339606878970603814755703167837480442251068230531926699205980639895012239254327439300220930923024855090117769633765709714826339834535876565538006788679271916019685164920493416004883901394115173882206447090610228518660081719399539376075038070034810020211340293423040766585888292494537662913458772049817318437606250938129574541767841602448300145138073940696983979059415445451195212528787305894819950526282403144596367019708209116488019479785136064985877899731579692549619154770180888669752809069235496303872000398374241532650796235196695916947874428693058258893424293987791471045924421366356810359849529988292704148275922733760964828717638828532352066259757744446229184986951298617242419115550392412022848989840586920941416655818223507527601871564570641408192234786458318407574121105566577710381048872914691225665311980882110415222436817149605338657757168302854397900614706332327212921851066498300381053609841762266343669520372320628210114413639485761915162414609422533174459519006397814257737889054381038101112761472099883783780140565576787975042564664143611845913471061951575941338844337411203552878275342039192198521263603180368307831236175304268307887495444496370405314855591523212253
Convert it into Decimal
from decimal import Decimal
Decimal(630078954945407486971302572117011329116721271139829179349572383637541443562605787816061110360853600744212572072073871985233228681677019488795915592613136558538697419369158961413804139004860949683711756764106408843746324318507090165961373116110504156510362261390086415758369311946617855091322330974469225379475157034653986221430086928768825350265642050874148148762850633380318092218497923938934331494944977897218250062378381926065651168047990017214673422724320097123140849040864223795967322521445859865961967502883479331506850337535224430391571038073324911164139663006137417510539192705821435391823658411385338369730232377028300695738866310468334377735439392551346134885024889217010755804062396901380184592416137322133531990680941959600864409332647120219490414701983979339375751465609840801484592889925172867105767663865003474673877306782492180067353856493873352082672833242368295700361941406607094298524971010582848155295175876416280789802070376313832361148791530700602039387918303750966965311391574707837728570176384970704855124594407172251268098706978376090542912929344492513384183231040016207412648019561891411057151352984928184115181483534959666911309714744265773932487092170761893895469807486999330039447615795396834925983574737750806569360090695009597077440117397176004125384806886783639660621550162794222825503301866755919064102371025428970202609474167093725973377029019369542489008907399816344268271107251422642444394295031677496626574918192538987307032199141725692286015261369012945174380684144484086524852886270717368426832490990772158458075266904766542991903970407465284703623099975166486775916952691073355877964592340230731529088307662462168730966089062336436389277513929792989509527961806655782453847736236387259057358913693838332016851781407524359352813229072505380650711693049176679191021591021389372641247384964875287336650708846120446276882272810745622693709331578317206645848042706067557480758511553310824640020649394355322305550804086562784060919544289531008318716584762468479626254129440271062831239695632816441075920969278753806765451632278698182308325313693381046301850639648800754286747096420253430423489479466804681482044272737999450499555465823164480037422222367329404142745283822947899313540404366082279717101515216147594766392292429511243594117952923319141560834706050302935730124475680758933436231491685270482951411606790235850929380027076481544634203449136248177171198738003486838372217932769689898884784243826855286091288358239337707121625402050851090825870703676300673135330647766969648618275025084598123309185991065848687389917566591933063673989563554382295252021136544002390268843474613430643976640252484632736275857290476774458675146529714463940660919706163233969511685041545624837717646981487338708223589261847530514133271116906741091917303278220653192405195999010112864383206483703165777476499412818478890639921457227974733696980927826881905040085772367856544559431242332068267736163848514181227641896012840513431718789320462329400102516689122316306450427759800832003864806238880726778463445628851437837462460535312158694258263309302240517780411649608046974426356882853543894970861987774349994574781336617336532821610244134603281437218963727001383319023603953398010028490193243704729281796345148350290421966348930850029874490245386530847693496493617805444480239004190850309960252932678216332242871877009997232445612436261407704091991812835292853218055207198699990193596327522065871513324383404436885617489886675946278629169614212976734843602198938090909080423822416990482891694415707626880182335127385564845496968722502531064508236794490149037021373756875425278069621745860863912399196641388414399463171257761192133719058891540419926061937259684055960761838199081600923840918336924120526335236516500115108241855287430263809480233364084000105646409638910878994420820422552248809062853062971314598633808334114010418924133364933998209352785219452456089337721022144079478199256501302345218342858278235244199769192326879823000937772497828914123378185067698603690831733524939588396025784744225418501083799649691393873269892335315415985069239360869306287430161725433942167215211261881754762154607113521244775811112287675881463204557903372983296624502192459971356246676084633217778109344434581417296897250881570580436981350693342923679859228288541131389540894299576663507525370715066110292813780358628483132303131742983176445700582642966318721896316623598268218673189722517718549132701529540520838922283977941956346618584749724827265852568855500361230814706488134611068845316354598799199730845206624628172917488457386459633185969341459672532379007964850480186110477536989316248137632870890622881765455399233258931339410494872048786445380805620853716965362789859403153144908183575383939310217279705139721560019568071214255994974408572648841828625948484183872232281767754936910627565103682925375742419024815987856586166378115801243175559269046804610268271061187624472308223805466602642940260042682812756256714586960165383407898099487002894444062178839391272002262993374941547876859908138330758067507911277955632733866611899695647351688393078353839611712871637384462404921878353336617815170011477929312619557000783485114417555469412886951873941491122663330089140640237525839190435611147175201365580352057169422983019756479705286311737745688878300295162035783336721495176173005235943366036579342403031858371914608154767616552994518813852963325330926988565056420401996182426971074864830358200261362270644352471067742908740066312532706251619727693803689605359722994531913085746256816708333207607372464782479204187957800323115042281681129259667352353517828344865153265302260116463924808962369896134974192415072584064052318417051648079212739917316031264326241507504548923934897411859282836187869534528811502263549599774513219264816628970416773822011462914052436110107140947441642811202817152783793620844688755256396789417685977459433814911438287855016776285922198699082347185992693560300125534315526770599208589855117129892234808497648798749646357191091546146105862763759843591202631705539149848234511495065117372464217143148171544816412125072538951795020039403886647971400954941112844849901590156966236341935249533139330401618307950786879596469984119359421473188358955907773883294422386655263220117627516995224969119904423765978663514224958566699689223512229385859291888846405683717180332460248187496572144703276206259527743572333980326718238070708650626983118629971542697495485252436024567421318695854715454101364076644687730899594195633275321940815295981062932643316855398782785214003121345721054960499469768201901436790482699005065113381322434770359397558788285726356480844311358408385253074776523383477020175018046561198787369898157059096899613482593561519419424142071652533171543891165116251895092189352681035517633166882961672980048326420273966474172389658068362117989909317156664012999905834065753973024952538940459359134550258647169854000824881036941617642608336413135147747841565829503975928572807411306180458140011310004983383026486015252188390643855363612216856777424655584758055581172316113883725410980557553123430983725023598059269514271705141359723255705532679522179269076133226643135890378252461618715340762528062563692617084267038794880235151507089462270896512581989114649911930878095396167316626567923044257435256806444296060636631937672317042925789128926010875180848009703217786800815516725253240060242786574356358801695111745961187387934689215227487920216703113061886444488110070984015605138767865701169972101412815405111287993463590619141283476936740880771219789950164205754467253452729863863950188739206664510955140236732140158021974750113109733958553067094099406873014624519007182600409029981781192576220342072442404407525694905182026252480724976436388060662190514332680872481044874701969108472815273272711817597987293115253454183720993206057768497928765003643915107639254922781596562385649150660525460064354624202531015121109364122338886448890343464196409635269404582149158284742251021906623863213747664602076214326636400706220794772134432273627481233425177349936452817255847706031575002057972719912748242114947097609007914285108694438842246267149271162583225184547641087826552789896176698128504268589381137327318145707839809327397245651593444250042725815049799745201372918555659842435159140214766015206264721726961406530774240071612440812084893955728905341340722978959370951469131953687044216423231488696742678073353379700564119257217803190999447776766945656573316206535726981650249163828677908520393197985243387213795555465230391800618144495416908755212757986378350464035578468435976351162791656892497974733578066603931101486067508297960437234016531761812630581332141184120753306673976159208563797007731706257116416221162110419311205495221132895418746168121064205944498701002545540456478596919625174145565742316551390140063146675199648332585331762709727331999408582325796339606878970603814755703167837480442251068230531926699205980639895012239254327439300220930923024855090117769633765709714826339834535876565538006788679271916019685164920493416004883901394115173882206447090610228518660081719399539376075038070034810020211340293423040766585888292494537662913458772049817318437606250938129574541767841602448300145138073940696983979059415445451195212528787305894819950526282403144596367019708209116488019479785136064985877899731579692549619154770180888669752809069235496303872000398374241532650796235196695916947874428693058258893424293987791471045924421366356810359849529988292704148275922733760964828717638828532352066259757744446229184986951298617242419115550392412022848989840586920941416655818223507527601871564570641408192234786458318407574121105566577710381048872914691225665311980882110415222436817149605338657757168302854397900614706332327212921851066498300381053609841762266343669520372320628210114413639485761915162414609422533174459519006397814257737889054381038101112761472099883783780140565576787975042564664143611845913471061951575941338844337411203552878275342039192198521263603180368307831236175304268307887495444496370405314855591523212253)
The best solution to this question runs in linear time. Here's the idea:
let's look at a shorter example: 1234
consider the total sum of the substrings which end on the ith digit (0..3)
substringsum[0]: 1 (we have only a single substring)
substringsum[1]: 2 + 12 (two substrings)
substringsum[2]: 3+23+123 (three substrings)
substringsum[3]: 4 + 34+234+1234
see a pattern?
let's look at substringsum[2]:
3 + 23 + 123 = 3 + 20+3 + 120+3 = 3*3 + 20+120 = 3*3 + 10*(2+12) = 3*3 +10*substringsum[1]
in general:
substringsum[k] = (k+1)*digit[k] + 10 * substringsum[k-1]
This you can compute in linear time.
This type of ideas is called "Dynamic Programming"
The overflow error suggest that there's an undesired conversion to float, which I assume you did not intend. The conversion happens because the type of 1e9 is float. To fix this, use % int(1e9+7) instead of % 1e9+7

Any better way to write this small code?

I'm processing a.CSV file in python which has a floating type field.
This field has to be modified such that it has at least 4 decimal points and max 8 decimal points of precision.
Example:
input: 5.15
output: 5.1500
input: -12.129999998
output: -12.12999999
What I'm currently doing:
#The field to be modifed is present at index 3 in list temp
dotIndex = temp[3].find('.') + 1
latLen = len(temp[3])-1
if (latLen) - (dotIndex) > 8:
temp[3] = temp[3][0:dotIndex+4]
elif (latLen) - (dotIndex) < 4:
temp[3] = temp[3][0:latLen] + (4 - (latLen - (dotIndex))) * '0'
Is there a better way to write this code to improve performance ?
this should work:
temp[3] = "{:.4f}".format(float(temp[3]))
Considering your comment and the fact you want it truncated, here you go:
n = len(temp[3].split('.')[1])
if n < 4:
temp[3] = "{:.4f}".format(float(temp[3]))
elif n > 8:
parts = temp[3].split('.')
temp[3] = parts[0]+"."+parts[1][:4]
If you're truncating, not rounding, you could use something like this:
def truncate_to_eight(val):
return '{:.8f}'.format((int(val * 10**8))/(10.0**8))
Multiplying by 10 to the power of 8, taking the integer part, and then dividing by 10 to the power 8 gets you the truncation required. Note however, this will always return a value with 8 decimal places - so 5.15 becomes 5.15000000.
You would use this by saying, for example:
rounded = truncate_to_eight(temp[3])

Round to whole numbers without using conditional statements in Python - Logic

I'm taking a Python course at Udacity, and I'm trying to work this out for myself without looking at the answer. Perhaps you can give me a hint for my logic?
Below are the instructions and what I have so far. We haven't learned conditional statements yet, so I can't use those. We've only learned how to assign/print a variable, strings, indexing strings, sub-sequences, and .find. They just introduced the str command in this final exercise.
# Given a variable, x, that stores the
# value of any decimal number, write Python
# code that prints out the nearest whole
# number to x.
# If x is exactly half way between two
# whole numbers, round up, so
# 3.5 rounds to 4 and 2.5 rounds to 3.
# You may assume x is not negative.
# Hint: The str function can convert any number into a string.
# eg str(89) converts the number 89 to the string '89'
# Along with the str function, this problem can be solved
# using just the information introduced in unit 1.
# x = 3.14159
# >>> 3 (not 3.0)
# x = 27.63
# >>> 28 (not 28.0)
# x = 3.5
# >>> 4 (not 4.0)
x = 3.54159
#ENTER CODE BELOW HERE
x = str(x)
dec = x.find('.')
tenth = dec + 1
print x[0:dec]
////
So this gets me to print the characters up to the decimal point, but I can't figure out how to have the computer check whether "tenth" is > 4 or < 5 and print out something according to the answer.
I figured I could probably get far enough for it to return a -1 if "tenth" wasn't > 4, but I don't know how I can get it to print x[0:dec] if it's < 5 and x[0:dec]+1 if it's > 4.
:/
Could someone please give me a nudge in the right direction?
This is a weird restriction, but you could do this:
x = str(x)
dec_index = x.find('.')
tenth_index = dec_index + 1
tenth_place = x[tenth_index] # will be a string of length 1
should_round_up = 5 + tenth_place.find('5') + tenth_place.find('6') + tenth_place.find('7') + tenth_place.find('8') + tenth_place.find('9')
print int(x[0:dec_index]) + should_round_up
What we do is look at the tenths place. Since .find() returns -1 if the argument isn't found, the sum of the .find() calls will be -4 if if the tenths place is 5, 6, 7, 8, or 9 (since one of the .find() calls will succeed and return 0), but will be -5 if the tenths place is 0, 1, 2, 3, or 4. We add 5 to that, so that should_round_up equals 1 if we should round up, and 0 otherwise. Add that to the whole number part, and we're done.
That said, if you weren't subject to this artificial restriction, you would do:
print round(x)
And move on with your life.
judging by the accepted answer you only expects floats so that is pretty trivial to solve:
x = 3.54159
# split on .
a, b = str(x).split(".")
# cast left side to int and add result of test for right side being greater or equal to 5
print(int(a) + (int(b) >= 5))
(int(b) > 5) will be either 1 or 0 i.e True/False so we either add 1 when right side is > .5 or flooring when it's < .5 and adding 0.
If you were doing it mathematically you just need to print(int(x+.5)), anything >= .5 will mean x will be rounded up and floored when it is < .5.
x = 3.54159
# split on .
a, b = str(x).split(".")
# cast left side to int and add result of test for right side being greater or equal to 5
print(int(a) + (int(b[0]) >= 5))
# above code will not work with 3.14567 and the number with having two or more digits after decimal
I think it's easier...
x = x + 0.5
intPart, decPart = str(x).split(".")
print intPart
Examples:
If x = 1, then it will become 1.5 and intPart will be 1.
If x = 1.1, then it will become 1.6 and intPart will be 1.
If x = 1.6, then it will become 2.1 and intPart will be 2.
Note: it will only work for positive numbers.
This code will round numbers to the nearest whole
without using conditionals
You can do it this way
x = 3.54159
x = x + 0.5 # This automatically takes care of the rounding
str_x = str(x) # Converting number x to string
dp = str_x.find('.') # Finding decimal point index
print str_x[:dp] # Printing upto but excluding decimal point
I did the same course at Udacity. solved it using the following code:
y = str(x)
decimal = y.find('.')
y_increment = y[decimal+1:]
print decimal
print y_increment
# Section below finds >5
check5 = y_increment.find('5',0,1)
check6 = y_increment.find('6',0,1)
check7 = y_increment.find('7',0,1)
check8 = y_increment.find('8',0,1)
check9 = y_increment.find('9',0,1)
yes_increment = (check5 + 1) + (check6 + 1) + (check7 + 1) + (check8 + 1) + (check9 + 1)
print check5, check6, check7, check8, check9
#Calculate rounding up
z = x + (yes_increment)
z = str(z)
final_decimal = z.find('.')
print z[:final_decimal]

Calculating a range of an exact number of values in Python

I'm building a range between two numbers (floats) and I'd like this range to be of an exact fixed length (no more, no less). range and arange work with steps, instead. To put things into pseudo Python, this is what I'd like to achieve:
start_value = -7.5
end_value = 0.1
my_range = my_range_function(star_value, end_value, length=6)
print my_range
[-7.50,-5.98,-4.46,-2.94,-1.42,0.10]
This is essentially equivalent to the R function seq which can specify a sequence of a given length. Is this possible in Python?
Thanks.
Use linspace() from NumPy.
>>> from numpy import linspace
>>> linspace(-7.5, 0.1, 6)
array([-7.5 , -5.98, -4.46, -2.94, -1.42, 0.1])
>>> linspace(-7.5, 0.1, 6).tolist()
[-7.5, -5.9800000000000004, -4.46, -2.9399999999999995, -1.4199999999999999, 0.10000000000000001]
It should be the most efficient and accurate.
See Recipe 66472: frange(), a range function with float increments (Python) with various float implementations, their pros and cons.
Alternatively, if precision is important to you, work with decimal.Decimal instead of float (convert to and then back) as answered in Python decimal range() step value.
def my_function(start, end, length):
len = length - 1
incr = (end-start) / len
r = [ start ]
for i in range(len):
r.append ( r[i] + incr )
return r
How about this:
def my_range_function(start, end, length):
if length <= 1: return [ start ]
step = (end - start) / (length - 1)
return [(start + i * step) for i in xrange(length)]
For your sample range, it returns:
[-7.5, -5.9800000000000004, -4.46,
-2.9399999999999995, -1.4199999999999999, 0.099999999999999645]
Of course it's full of round errors, but that's what you get when working with floats.
In order to handle the rounding errors, the following code utilizes Python's decimal module. You can set the rounding; for this sample I've set it to two decimal points via round_setting = '.01'. In order to handle any rounding errors, the last step is adjusted to the remainder.
Code
#!/usr/bin/env python
# encoding: utf-8
from __future__ import print_function
import math
import decimal
start_value = -7.5
end_value = 0.1
num_of_steps = 6
def my_range(start_value, end_value, num_of_steps):
round_setting = '.01'
start_decimal = decimal.Decimal(str(start_value)).quantize(
decimal.Decimal(round_setting))
end_decimal = decimal.Decimal(str(end_value)).quantize(
decimal.Decimal(round_setting))
num_of_steps_decimal = decimal.Decimal(str(num_of_steps)).quantize(
decimal.Decimal(round_setting))
step_decimal = ((end_decimal - start_decimal) /
num_of_steps_decimal).quantize(decimal.Decimal(round_setting))
# Change the last step in case there are rounding errors
last_step_decimal = (end_decimal - ((num_of_steps - 1) * step_decimal) -
start_decimal).quantize(decimal.Decimal(round_setting))
print('Start value = ', start_decimal)
print('End value = ', end_decimal)
print('Number of steps = ', num_of_steps)
print('Normal step for range = ', step_decimal)
print('Last step used for range = ', last_step_decimal)
my_range(start_value, end_value, num_of_steps)
Output
$ ./fixed_range.py
Start value = -7.50
End value = 0.10
Number of steps = 6
Normal step for range = 1.27
Last step used for range = 1.25
From there you can use the normal step and the last step to create your list.

Categories