Matematiska moduler i Python Decimal och Fractions

Även de mest grundläggande matematiska operationerna kan ibland ge ett felaktigt resultat. Detta händer på grund av begränsningar vid lagring av exakt värde för vissa nummer. Du kan övervinna dessa begränsningar genom att använda decimalmodulen i Python. På samma sätt varken matematik inte heller CMATH modul som vi lärde oss om i vår senaste handledning kan hjälpa oss att göra fraktionsbaserad aritmetik. Emellertid gör fraktionsmodulen i Python exakt det.

I denna handledning kommer du att lära dig om båda dessa moduler och de olika funktionerna de gör tillgängliga. 

Varför behöver vi en decimal modul?

Du undrar förmodligen varför vi behöver en modul för att göra grundläggande aritmetik med decimaltal när vi redan kan göra detsamma med floats.

Innan jag svarar på den här frågan vill jag att du ska ta en gissning om utgångsvärdet om du skriver 0,1 + 0,2 i Python-konsolen. Om du gissade att produktionen ska vara 0,3, blir du förvånad när du kolla in det faktiska resultatet, vilket är 0,30000000000000004. Du kan prova någon annan beräkning som 0,05 + 0,1 och du får 0,15000000000000002. 

För att förstå vad som händer här, försök att representera 1/3 i decimalform och du kommer att märka att numret faktiskt inte är avslutande i basen 10. På samma sätt är vissa nummer som 0,1 eller 1/10 inte avslutande i bas 2. Eftersom dessa nummer fortfarande måste representeras på något sätt, några approximationer görs när de lagras, vilket resulterar i dessa fel.

Antalet 0,30000000000000004 är faktiskt mycket nära 0,3, så vi kan komma undan med denna approximation större delen av tiden. Tyvärr kommer denna approximation inte att skära den när du simulerar en satellitlansering eller hanterar pengar. Ett annat problem med dessa approximationer är att felen fortsätter att hälla upp sig. 

För att få exakta resultat som de vi brukar hantera när man gör beräkningar för hand, behöver vi något som stöder snabb, korrekt avrundad, decimal flytande punkträkning, och decimal- modulen gör exakt det.

Använda den decimala modulen

Innan du använder modulen måste du importera den först. Därefter kan du skapa decimaler från heltal, strängar, floats eller tuples. När decimalen är uppbyggd av ett heltal eller en float, finns det en exakt omvandling av värdet av det numret. Ta en titt på exemplen nedan för att se vad jag menar:

från decimalimporten Decimal Decimal (121) # Retur Decimal ('121') Decimal (0,05) # Avkastning Decimal ('0.05000000000000000277555756') Decimal ('0.05') # Retur Decimal ('0,05 ') Decimal ((0, 3, 2, 4), -3)) Returnerar Decimal ('8.324') Decimal ((1, (8, 3, 2, 4), -1)) # returnerar Decimal ('- 832.4')

Som du kan se, värdet av Decimal (0,05) är något annorlunda än Decimal ( '0,05'). Det betyder att när du lägger till 0,05 och 0,1 bör du använda decimal.Decimal ( '0,05') och decimal.Decimal ( '0,1') att konstruera decimalerna.

från decimalimporten Decimal Decimal ('0.05') + Decimal ('0.1') # Retur Decimal ('0.15') Decimal (0,05) + Decimal (0,1) # Avkastning Decimal ('0.1500000000000000083266726847')

Nu när du kan utföra olika operationer på decimaler, kanske du vill kontrollera precisionen eller avrundningen för dessa operationer. Detta kan göras genom att använda getcontext () fungera. Med den här funktionen kan du få lika bra värde som precision och avrundningsalternativ, bland annat. 

Tänk på att både avrundning och precision kommer till spel endast under aritmetiska operationer och inte när du skapar decimalerna själva.

import decimaltal från decimalimporten Decimal, getcontext Decimal (1) / Decimal (13) # returnerar Decimal ('0.07692307692307692307692307692') getcontext (). prec = 10 Decimal (0.03) # returnerar Decimal ('0.02999999999999999888977697537') Decimal (1) / Decimal (7) # returnerar Decimal ('0.1428571429') getcontext (). Rounding = decimal.ROUND_DOWN Decimal (1) / Decimal (7) # returnerar Decimal ('0.1428571428') 

Du kan också använda några av de matematiska funktionerna som sqrt (), exp (), och logga() med decimaler. Här är några exempel:

import decimaltal från decimalimporten Decimal, getcontext Decimal (2) .sqrt () # returnerar Decimal ('1.414213562373095048801688724') getcontext (). prec = 4 Decimal ('2'). sqrt () # returnerar Decimal ('1.414') Decimal ('2000'). Log10 () # returnerar Decimal ('3.301')

Använda fraktionsmodulen

Ibland kan du möta situationer där du behöver utföra olika operationer på fraktioner eller slutresultatet måste vara en bråkdel. Fraktionsmodulen kan vara till stor hjälp i dessa fall. Det låter dig skapa en Fraktion Exempel från siffror, flottor, decimaler och jämnsträngar. Precis som decimalmodulen finns det några problem med den här modulen när det gäller att skapa fraktioner från flottor. Här är några exempel:

från fraktioner import Fraktion från decimalimport Decimal Fraktion (11, 35) # Returer Fraktion (11, 35) Fraktion (10, 18) # Returer Fraktion (5, 9) Fraktion ('8/25') # Returer Fraktion (8, 25) Fraktion (1,13) # returnerar Fraktion (1272266894732165, 1125899906842624) Fraktion ('1.13') # returnerar Fraktion (113, 100) Fraktion (Decimal ('13,13 '))

Du kan också utföra enkla matematiska operationer som tillägg och subtraktion på fraktioner precis som vanliga nummer.

från fraktioner import Fraktion Fraktion (113, 100) + Fraktion (25, 18) # Returer Fraktion (2267, 900) Fraktion (18, 5) / Fraktion (18, 10) # Returer Fraktion (2, 1) Fraktion (18, 5) * Fraktion (16, 19) # returnerar Fraktion (288, 95) Fraktion (18, 5) * Fraktion (15, 36) # Returer Fraktion (3, 2) Fraktion (12, 5) ** Fraktion 10) # returnerar 2.8592589556010197

Modulen har också några viktiga metoder som limit_denominator (max_denominator) som kommer att hitta och returnera en fraktion närmast i värde till den angivna fraktionen vars nämnare är högst max_denominator. Du kan också returnera täljaren av en viss fraktion på lägsta termen med hjälp av täljare egendom och nämnare genom att använda nämnare fast egendom.

från fraktioner importera Fraktionsfraktion ('3.14159265358979323846') # returnerar Fraktion (157079632679489661923, 50000000000000000000) Fraktion ('3.14159265358979323846'). limit_denominator (10000) # returnerar Fraction (355, 113) Fraction ('3.14159265358979323846'). limit_denominator Fraktion (311, 99) Fraktion ('3.14159265358979323846'). Limit_denominator (10) # returnerar Fraktion (22, 7) Fraktion (125, 50) .numerator # returnerar 5 Fraktion (125, 50) .genominator # returnerar 2

Du kan också använda denna modul med olika funktioner i matematik modul för att utföra fraktionsbaserade beräkningar.

import matematik från fraktioner import Fraktion math.sqrt (Fraktion (25, 4)) # returnerar 2,5 math.sqrt (Fraction (28,3)) # returnerar 3,0550504633038935 math.floor (Fraction (3558, 1213)) # returnerar 2 Fraction math.sin (math.pi / 3)) # return Fraction (3900231685776981, 4503599627370496) Fraktion (math.sin (math.pi / 3)) limit_denominator (10) # returnerar Fraction (6, 7)

Slutgiltiga tankar

Dessa två moduler ska vara tillräckliga för att hjälpa dig att utföra vanliga operationer på både decimaler och fraktioner. Som visas i det sista avsnittet kan du använda dessa moduler tillsammans med matematikmodulen för att beräkna värdet på alla typer av matematiska funktioner i det format du önskar.

I nästa handledning av serien kommer du att lära dig om slumpmässig modul i Python.