fractions - Numeri Razionali

Scopo: Implementa una classe per lavorare coi numeri razionali

La classe Fraction implementa operazioni numeriche su numeri razionali basate sull'API definita nel modulo numbers da Rational.

Creare Istanze di Fraction

Così come per il modulo decimal nuovi valori possono essere creati in svariati modi. Uno dei più facili è crearli da valori di numeratore e denominatore separati.

# fractions_create_integers.py

import fractions

for n, d in [(1, 2), (2, 4), (3, 6)]:
    f = fractions.Fraction(n, d)
    print('{}/{} = {}'.format(n, d, f))

Il comun denominatore più basso viene mantenuto mentre vengono calcolati i nuovi valori.

$ python3 fractions_create_integers.py

1/2 = 1/2
2/4 = 1/2
3/6 = 1/2

Un altro modo di creare una frazione con Fraction è usare una rappresentazione stringa di numeratore/denominatore.

# fractions_create_strings.py

import fractions

for s in ['1/2', '2/4', '3/6']:
    f = fractions.Fraction(s)
    print('{} = {}'.format(s, f))

La stringa viene elaborata per trovare i valori di numeratore e denominatore.

3 fractions_create_strings.py

1/2 = 1/2
2/4 = 1/2
3/6 = 1/2

Le stringhe possono anche utilizzare la più comune notazione decimale od a virgola mobile di serie di cifre separate da un punto. E' supportata qualsiasi stringa che possa essere elaborata da float() e che non rappresenti un "non numero" (NaN) oppure un valore infinito.

# fractions_create_strings_floats.py

import fractions

for s in ['0.5', '1.5', '2.0', '5e-1']:
    f = fractions.Fraction(s)
    print('{0:>4} = {1}'.format(s, f))

I valori del numeratore ed il denominatore rappresentati dal valore a virgola mobile vengono calcolati automaticamente.

$ python3 fractions_create_strings_floats.py

 0.5 = 1/2
 1.5 = 3/2
 2.0 = 2
5e-1 = 1/2

E' anche possibile creare istanze di Fraction direttamente da altre rappresentazioni di valori razionali, tipo float o Decimal.

# fractions_from_float.py

import fractions

for v in [0.1, 0.5, 1.5, 2.0]:
    print('{} = {}'.format(v, fractions.Fraction(v)))

I valori a virgola mobile che non possono essere espressi esattamente potrebbero contenere risultati inaspettati.

$ python3 fractions_from_float.py

0.1 = 3602879701896397/36028797018963968
0.5 = 1/2
1.5 = 3/2
2.0 = 2

L'utilizzo di rappresentazioni decimal dei valori fa ottenere i risultati attesi.

# fractions_from_decimal.py

import decimal
import fractions

values = [
    decimal.Decimal('0.1'),
    decimal.Decimal('0.5'),
    decimal.Decimal('1.5'),
    decimal.Decimal('2.0'),
]

for v in values:
    print('{} = {}'.format(v, fractions.Fraction(v)))

L'implementazione interna di decimal non subisce gli errori di precisione propri della rappresentazione standard dei valori a virgola mobile.

$ python3 fractions_arithmetic.py

1/2 + 3/4 = 5/4
1/2 - 3/4 = -1/4
1/2 * 3/4 = 3/8
1/2 / 3/4 = 2/3

Aritmetica

Una volta che le frazioni sono state istanziate, possono essere utilizzate in espressioni matematiche.

# fractions_arithmetic.py

import fractions

f1 = fractions.Fraction(1, 2)
f2 = fractions.Fraction(3, 4)

print('{} + {} = {}'.format(f1, f2, f1 + f2))
print('{} - {} = {}'.format(f1, f2, f1 - f2))
print('{} * {} = {}'.format(f1, f2, f1 * f2))
print('{} / {} = {}'.format(f1, f2, f1 / f2))

Sono supportati tutti gli operatori standard.

$ python3 fractions_from_decimal.py

0.1 = 1/10
0.5 = 1/2
1.5 = 3/2
2.0 = 2

Approssimazione dei Valori

Una utile caratteristica di Fraction è la capacità di convertire un numero a virgola mobile in un valore razionale approssimato.

# fractions_limit_denominator.py

import fractions
import math

print('PI       =', math.pi)

f_pi = fractions.Fraction(str(math.pi))
print('Nessun limite =', f_pi)

for i in [1, 6, 11, 60, 70, 90, 100]:
    limited = f_pi.limit_denominator(i)
    print('{0:8} = {1}'.format(i, limited))

Il valore della frazione può essere controllato limitando la dimensione del denominatore.

$ python3 fractions_limit_denominator.py

PI       = 3.141592653589793
Nessun limite = 3141592653589793/1000000000000000
       1 = 3
       6 = 19/6
      11 = 22/7
      60 = 179/57
      70 = 201/64
      90 = 267/85
     100 = 311/99

Vedere anche:

fractions
La documentazione della libreria standard per questo modulo.
decimal
Il modulo decimal fornisce una API per matematica su valori fissi e a virgola mobile
Note di portabilità
Le note di portabilità per fractions