La precisione del computer

egraphIo sono in ferie, niente post impegnativi. Ma un piccolo resoconto di ieri forse ci può stare; e se interessa poi si continua.
Mi è venuto a trovare il giovane G. che forse si fa un blog tutto suo –prossimamente– chiedendomi: “quanto sono precisi i calcoli fatti con il computer?”. Dipende, ho risposto ma non era sufficiente e siamo scivolati in una sessione di roba che adesso riassumo.
Invece di continuare con π di cui o già raccontato ho proposto e di Eulero e/o Nepero, questo insomma.
L’ispirazione me l’ha data Marco Fulvio Barozzi (Popinga) che aveva appena pubblicato una breve poesia e la sua traduzione:

eIo sono un evangelista Python, possibilmente con Linux e allora ecco:

#!/usr/bin/python3

x = 0.1
eprec = 2.59
for c in range(21):
	n = (1 + x) ** (1 / x)
	print(c, x, n, n - eprec)
	x /= 10
	eprec = n

py

Non benissimo, anzi… Dopo poche iterazioni l’approssimazione diventa disastrosa.
Sono anche evangelista newLISP; sì, lo so, sono perfettamente consapevole che la cosa non è molto popolare (e newLISP non piace ai lispisti (o si deve dire lispers?)) ma è piccolo, veloce, efficiente, insomma ecco:

#!/usr/bin/newlisp

(set-locale "C" ".")
(set 'eprec 2.59)
(for (c 1 20) (
    (set 'x (div 1 (pow 10 c))
         'n (pow (add 1 x) (div 1 x)))
    (print c " " x " " n " " (sub n eprec) "\n")
    (set 'x (div x 10)
         'eprec n)
))
(exit)

nl

Non meglio di Python, sigh! Notare poi alcune cose inusuali: 1) per la mia abitudine di usare il punto come separatore decimale ho dovuto dire all’interprete di non considerare le impostazioni locali; 2) per i numeri float non si usano i soliti operatori aritmetici +, -, * e / ma add, sub, times e div; 3) la prima versione usava il contatore c solo come indice del ciclo for con l’effetto non voluto che visto che non veniva mai usata anche x veniva considerata costante (ci sarebbe un lungo discorso da fare qui); 4) le parentesi spaventano i novizi ma con un editor che segnala le corrispondenze (io uso Gedit) il problema è solo apparente.

In ogni caso non ci siamo. E poi c’è –ovviamente– un modo molto più semplice:

predef

E senza programmare c’è il foglio di calcolo, qui Gnumeric:

gnu2

E se vogliamo essere precisi, eravamo partiti di lì?
OK, ci sono tante possibilità, per esempio con Linux abbiamo bc e calc. Siccome calc è il mio preferito gli abbiamo dato una possibilità:

#!/usr/bin/calc -f

x = 0.1;
eprec = 2.59;
for (c = 0; c < 10; c++) {
    n = (1 + x) ** (1 / x);
    print c, x, n, n - eprec;
    x /= 10;
    eprec = n;
}

blovk

Disastroso! Le prime iterazioni sono velocissime poi diventa lentissimissimo. L’ho interrotto dopo qualche ora, G. mi aveva già abbandonato. Abbandonare calc? No, al solito sto sbagliando tutto!

Data usa scorsa alla documentazione ecco un versione molto più efficiente:

#!/usr/bin/calc -f

r = config("display", 40);
print(exp(1, 1e-10))
print(exp(1, 1e-20))
print(exp(1, 1e-30))
print(exp(1, 1e-40))

calc-e1

OK? Sì abbiamo limitato la precisione a 40 cifre ma volendo…
Resta da vedere bc, che fa parte di Linux (e Unix) da sempre. E anche su calc ci sarebbero ancora cose da dire. Prossimamente, se interessa, qui o sul nuovo blog di G. (quando torna dalle ferie, lui le fa davvero, adesso è in giro in camper con mamma e papà).

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • Marco Bruno  Il 14 agosto 2014 alle 11:55

    Interessante, da ferie, appunto. Ho sempre avuto l’impressione che questo tipo di esperimenti funzioni soprattutto se conosci già il risultato. Diversamente, devi conoscere bene, ma bene, lo strumento che usi, o ti fidi ciecamente. Se hai un’dea degli ordini di grandezza dei risultati va ancora bene; ma in calcoli veramente complessi è dura, bisogna avere la voglia (e il tempo, e la capacità) di rifarli in un altro sistema/linguaggio.

    • juhan  Il 14 agosto 2014 alle 12:00

      Certo. Poi per la precisione dipende: a mente uso π = 3 e, per l’ordine di grandezza, π = 1.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: