Discussione:
Quanti byte per un intero?
(troppo vecchio per rispondere)
mulkrul
2010-10-06 18:19:32 UTC
Permalink
Sto muovendo i primi passi con Python ed ho già notato un paio di cose "strane" rispetto a linguaggi tipo Pascal,
Fortran e C. Di solito vengono dedicati due byte alla memorizzazione di un numero intero per cui il maxint è 2^15=32768.
In Python ho realizzato un piccolo script che calcola il fattoriale di un numero mediante una funzione ricorsiva:

def Fattoriale(n):
if n==0:
return 1
else:
return n*Fattoriale(n-1)

n=input("Inserisci un numero naturale: ")
print "\n Il fattoriale di: ",n," e': ",Fattoriale(n)

Dato che il fattoriale cresce molto rapidamente, mi aspettavo dei risultati sballati già nel calcolo di 8!=40320 ed
invece, con mio grande stupore, il mio script riesce a calcolare correttamente perfino 998!=
402790050127220994538240674597601587306681545756471103647447357787726238637266286878923131618587992793273261872069265323955622495490298857759082912582527118115540044131204964883707335062250983503282788739735011132006982444941985587005283378024520811868262149587473961298417598644470253901751728741217850740576532267700213398722681144219777186300562980454804151705133780356968636433830499319610818197341194914502752560687555393768328059805942027406941465687273867068997087966263572003396240643925156715326363340141498803019187935545221092440752778256846166934103235684110346477890399179387387649332483510852680658363147783651821986351375529220618900164975188281042287183543472177292257232652561904125692525097177999332518635447000616452999984030739715318219169707323799647375797687367013258203364129482891089991376819307292252205524626349705261864003453853589870620758596211518646408335184218571196396412300835983314926628732700876798309217005024417595709904449706930796337798861753941902125964936412501007284147114260935633196107341423863071231385166055949914432695939611227990169338248027939843597628903525815803809004448863145157344706452445088044626373001304259830129153477630812429640105937974761667785045203987508259776060285826091261745049275419393680613675366264232715305430889216384611069135662432391043725998805881663054913091981633842006354699525518784828195856033032645477338126512662942408363494651203239333321502114252811411713148843370594801145777575035630312885989779863888320759224882127141544366251503974910100721650673810303577074640154112833393047276025799811224571534249672518380758145683914398263952929391318702517417558325636082722982882372594816582486826728614633199726211273072775131325222240100140952842572490801822994224069971613534603487874996852498623584383106014533830650022411053668508165547838962087111297947300444414551980512439088964301520461155436870989509667681805149977993044444138428582065142787356455528681114392680950815418208072393532616122339434437034424287842119316058881129887474239992336556764337968538036861949918847009763612475872782742568849805927378373244946190707168428807837146267156243185213724364546701100557714520462335084082176431173346929330394071476071813598759588818954312394234331327700224455015871775476100371615031940945098788894828812648426365776746774528000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

mentre con 999! sballa per eccesso di ricorsione.
Mi sembra di capire che non ci sia quindi un uno spazio predeterminato per la memorizzazione di un intero. Sbaglio?

Altra questione: Python introduce un sensibile errore nel calcolo di sin(pi) che dovrebbe fare 0 (e tutte le
calcolatrici che possiedo lo calcolano correttamente). Infatti il seguenta script:

import math
print math.sin(math.pi)

mi dà come risultato: 1.22460635382e-16

Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera e questa "grossolanità" nei calcoli in virgola
mobile?
David
2010-10-06 18:48:09 UTC
Permalink
Post by mulkrul
Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera e questa "grossolanità" nei calcoli in virgola
mobile?
Stai dando a python colpe che non ha. Non c'è nessuna grossolanità.
Semplicemente la rappresentazione finita di un numero irrazionale è
inevitabilmente affetta da un errore.
Altre piattaforme lo approssimano, python invece è onesto e te lo fa vedere.
Post by mulkrul
0.1+0.2 == 0.3
False

http://pyfaq.infogami.com/why-are-floating-point-calculations-so-inaccurate
Claudio_F
2010-10-06 18:54:02 UTC
Permalink
Post by mulkrul
stupore, il mio script riesce a calcolare correttamente perfino 998!=
Da me arriva a 995, e scommetto che su pc diversi il valore cambia ancora...
Post by mulkrul
Mi sembra di capire che non ci sia quindi un uno spazio predeterminato
per la memorizzazione di un intero. Sbaglio?
In Python si ragiona ad un livello piu' astratto, per cui un numero (e
altre cose) è lungo quanto la macchina riesce a calcolarlo, il vantaggio
e' che ci si concentra sui valori e non sulle loro
rappresentazioni/occupazioni fisiche, lo svantaggio e' che questo e'
meno efficiente come velocita'.
Post by mulkrul
Altra questione: Python introduce un sensibile errore nel calcolo di
sin(pi) che dovrebbe fare 0 (e tutte le calcolatrici che possiedo lo
calcolano correttamente).
La mia calcolatrice scientifica ha 10 cifre, se il tuo calcolo lo
rappresentiamo con solo 10 cifre dopo la virgola otteniamo zero spaccato:

print "%0.10f" % math.sin(math.pi)

...imho, la calcolatrice puo' avere un errore maggiore ma non si vede ;)



ciao
Claudio_F
Claudio_F
2010-10-06 19:33:37 UTC
Permalink
Post by Claudio_F
...imho, la calcolatrice puo' avere un errore maggiore ma non si vede ;)
Anzi, ce l'ha, e anche bello grande: facciamo 1.0 / 3.0

calcolatrice: 0 . 333 333 333 334 000 00
python......: 0 . 333 333 333 333 333 31

la calcolatrice produce un errore di approssimazione oltre 30mila volte
piu' grande!




ciao
Claudio_F
mulkrul
2010-10-07 19:04:18 UTC
Permalink
Altra questione: Python introduce un sensibile errore nel calcolo di sin(pi) che dovrebbe fare 0 (e tutte le
calcolatrici che possiedo lo
calcolano correttamente).
La mia calcolatrice scientifica ha 10 cifre, se il tuo calcolo lo rappresentiamo con solo 10 cifre dopo la virgola
Questa spiegazione sarebbe plausibile se la calcolatrice lavorasse con numeri in virgola fissa. Quella che ho in mano in
questo momento ha un display a 8 cifre ed il numero (positivo) più piccolo che riesce a trattare è 1e-99 quindi, se
calcolasse la funzione seno alla maniera di Python, mi dovrebbe dare:

sin(pi)=1.2246e-16

invece mi dà sin(pi)=0

Grazie
Ciao
Claudio_F
2010-10-07 19:21:45 UTC
Permalink
Post by mulkrul
Questa spiegazione sarebbe plausibile se la calcolatrice lavorasse con
numeri in virgola fissa.
Ni, il problema della floating-point (vale anche per le calcolatrici) e'
la lunghezza della mantissa che puo' rappresentare un numero ridotto di
cifre. Se fai:

a = 1234567890123456789.1234567890123456789
print a

ottieni: 1.23456789012e+018
e non: 1.2345678901234567891234567890123456789e+18

infatti facendolo ristampare per esteso con tutti i decimali:

print "%0.19f" % a

ottieni: 1234567890123456800.0000000000000000000

cioe' hai solo 17 cifre rappresentabili (con l'ultima non certa) e le
altre si perdono, indipendentemente dal valore dell'esponente.



ciao
Claudio_F
Antonio Cuni
2010-10-07 06:47:49 UTC
Permalink
Post by mulkrul
Sto muovendo i primi passi con Python ed ho già notato un paio di cose
"strane" rispetto a linguaggi tipo Pascal, Fortran e C. Di solito
vengono dedicati due byte alla memorizzazione di un numero intero per
cui il maxint è 2^15=32768.
oddio, quel che dici è vero per una qualche definizione di "di solito" :-).

Se parliamo di CPU intel e sistemi operativi Microsoft, gli interi a 16 bit
erano usati da quei compilatori che dovevano produrre codice compatibile con
MS-DOS (la cosiddetta "modalità reale"). Da Windows 95 in poi, è stato
possibile eseguire programmi in modalità protetta, in cui gli interi sono
rappresentati a 32 bit.

Inoltre al giorno d'oggi, se hai un processore a 64 bit (ovvero, tutti quelli
di ultima generazione), è possibile che il compilatore decida di avere int a
64 bit: questo è sicuramente vero su linux, anche se non ho idea di quale sia
la convenzione di windows.

Detto questo, in Python la dimensione di un intero corrisponde direttamente
alla dimensione dell'int sottostante in C. Puoi vederlo usando l'attributo
Post by mulkrul
sys.maxint
2147483647

Come puoi vedere, la mia macchina corrente è a 32 bit.

Tuttavia, a differenza di altri linguaggi in Python non esiste il concetto di
overflow: quando il risultato di un'operazione tra interi è maggiore di
sys.maxint (o minore di -sys.maxint-1) Python passa automaticamente al tipo
"long". Occhio che il "long" di Python non corrisponde affatto al "long" del
C, ma si tratta di una rappresentazione a precisione arbitraria, in cui il
numero massimo rappresentabile è limitato solamente dalla quantità di memoria
disponibile nel sistema.
Post by mulkrul
type(sys.maxint)
<type 'int'>
Post by mulkrul
type(sys.maxint+1)
<type 'long'>

Questo vale solo per Python 2.x. Se stai usando Python 3, esiste solo il tipo
"int" ma che in realtà si comporta come il tipo "long" di Python 2 (quindi,
precisione arbitraria). La buona notizia è che per la maggior parte degli
utilizzi pratici, puoi tranquillamente ignorare la distinzione e semplicemente
goderti le tue operazioni che funzionano :-).
Post by mulkrul
Altra questione: Python introduce un sensibile errore nel calcolo di
sin(pi) che dovrebbe fare 0 (e tutte le calcolatrici che possiedo lo
import math
print math.sin(math.pi)
mi dà come risultato: 1.22460635382e-16
Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera
e questa "grossolanità" nei calcoli in virgola mobile?
già altri ti hanno spiegato che i numeri in virgola mobile non sono mai
rappresentati correttamente all'interno del sistema, quindi non otterrai mai
dei risultati completamente esatti.

Questo vale in generale, e ancor di più nel caso particolare di math.pi: per
ovvi motivi il numero contenuto in math.pi *non* è pi greco, ma una sua
approssimazione. Nessuna sorpresa quindi che
sin(numero-molto-simile-a-pi-greco-ma-che-in-realtà-non-lo-è) non dia 0 :-).

A livello pratico, quello che si fa di solito è di stampare i numeri floating
point arrotondando ad una certa cifra decimale (che poi è quello che fanno
anche la calcolatrici).
Post by mulkrul
print '%0.5f' % math.sin(math.pi)
0.00000

ciao,
Anto
--
Antonio Cuni
http://morepypy.blogspot.com/
Gerolamo
2010-10-07 13:30:52 UTC
Permalink
Post by Antonio Cuni
Inoltre al giorno d'oggi, se hai un processore a 64 bit (ovvero,
tutti quelli di ultima generazione), è possibile che il compilatore
decida di avere int a 64 bit: questo è sicuramente vero su linux,
anche se non ho idea di quale sia la convenzione di windows.
Python 2.7 (r27:82525, Jul 4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)] on
win32
Type "copyright", "credits" or "license()" for more information.
Post by Antonio Cuni
import sys
sys.maxint
2147483647
--
Gerolamo
Antonio Cuni
2010-10-07 13:32:43 UTC
Permalink
Post by Antonio Cuni
Inoltre al giorno d'oggi, se hai un processore a 64 bit (ovvero,
tutti quelli di ultima generazione), è possibile che il compilatore
decida di avere int a 64 bit: questo è sicuramente vero su linux,
anche se non ho idea di quale sia la convenzione di windows.
Python 2.7 (r27:82525, Jul 4 2010, 07:43:08) [MSC v.1500 64 bit (AMD64)]
on win32
^^^^

a quanto pare, qui stai eseguendo una versione a 32 bit di windows su una
macchina a 64 bit. Sarebbe interessante vedere cosa succede ad usare win64
anziché win32.

ciao,
Anto
--
Antonio Cuni
http://morepypy.blogspot.com/
Gerolamo
2010-10-07 13:46:17 UTC
Permalink
Post by Antonio Cuni
Post by Antonio Cuni
Inoltre al giorno d'oggi, se hai un processore a 64 bit (ovvero,
tutti quelli di ultima generazione), è possibile che il compilatore
decida di avere int a 64 bit: questo è sicuramente vero su linux,
anche se non ho idea di quale sia la convenzione di windows.
Python 2.7 (r27:82525, Jul 4 2010, 07:43:08) [MSC v.1500 64 bit
(AMD64)] on win32
^^^^
a quanto pare, qui stai eseguendo una versione a 32 bit di windows su
una macchina a 64 bit. Sarebbe interessante vedere cosa succede ad
usare win64 anziché win32.
suona strano anche a me, ma quella macchina è un Win2008 Server R2
a 64 bit virtualizzato su XEN (sotto c'è una Debian e dei processoni Xeon)
e il python installato l'ho scaricato mezz'ora fa da qui:

http://www.python.org/ftp/python/2.7/python-2.7.amd64.msi

non so perchè riporti "on win32"....
--
Gerolamo
mulkrul
2010-10-07 19:14:41 UTC
Permalink
Post by Antonio Cuni
oddio, quel che dici è vero per una qualche definizione di "di solito" :-).
[cut]

Ti ringrazio per l'esauriente spiegazione.
Post by Antonio Cuni
Post by mulkrul
Altra questione: Python introduce un sensibile errore nel calcolo di
sin(pi) che dovrebbe fare 0 (e tutte le calcolatrici che possiedo lo
import math
print math.sin(math.pi)
mi dà come risultato: 1.22460635382e-16
Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera
e questa "grossolanità" nei calcoli in virgola mobile?
già altri ti hanno spiegato che i numeri in virgola mobile non sono mai rappresentati correttamente all'interno del
sistema, quindi non otterrai mai dei risultati completamente esatti.
Questo vale in generale, e ancor di più nel caso particolare di math.pi: per ovvi motivi il numero contenuto in
math.pi *non* è pi greco, ma una sua approssimazione. Nessuna sorpresa quindi che
sin(numero-molto-simile-a-pi-greco-ma-che-in-realtà-non-lo-è) non dia 0 :-).
Come spieghi che con Derive 6.0 il risultato (approssimato) di sin(pi) è zero indipendentemente dal numero di cifre di
precisione impostato? Ho provato con 10, 100, 1000 cifre significative!

Ciao
g***@SANMARTINO.CABIATE.IT
2010-10-07 19:44:11 UTC
Permalink
Post by mulkrul
sin(pi) mi dà come risultato: 1.22460635382e-16
Wikipedia> The diameter of the nucleus is in the range of 1.75 fm
Wikipedia> (1.75×10−15 m) for hydrogen to about 15 fm for the heaviest
Wikipedia> atoms, such as uranium.
Post by mulkrul
Come spieghi che con Derive 6.0 il risultato (approssimato) di sin(pi)
è zero
questa la so, questa la so!

derive fa algebra simbolica e _sa_ che il seno di pi è zero (e io so che
tu sai che derive sa)
mulkrul
2010-10-08 17:36:38 UTC
Permalink
Post by g***@SANMARTINO.CABIATE.IT
Post by mulkrul
Come spieghi che con Derive 6.0 il risultato (approssimato) di sin(pi)
è zero
questa la so, questa la so!
derive fa algebra simbolica e _sa_ che il seno di pi è zero (e io so che
tu sai che derive sa)
Derive esegue sia calcoli esatti che approssimati. Ad esempio, se inserisci sin(pi/4) e clicchi su
Semplifica--->Sviluppa--->Sviluppa ottieni come risultato sqrt(2)/2 mentre se clicchi su
Semplifica--->Approssima--->Approssima ottieni (con 10 cifre di precisione) 0.7071067811
Giuseppe Di Martino
2010-10-08 11:40:39 UTC
Permalink
Post by mulkrul
import math
print math.sin(math.pi)
mi dà come risultato: 1.22460635382e-16
Hai presente che 1.22460635382e-16 equivale a 0.000000000000000122460... ?
e che quindi visualizzando le prime 10 cifre otterrai 0 ?

Giuseppe
Claudio_F
2010-10-08 16:34:35 UTC
Permalink
Post by Giuseppe Di Martino
Hai presente che 1.22460635382e-16 equivale a 0.000000000000000122460... ?
e che quindi visualizzando le prime 10 cifre otterrai 0 ?
Tuttavia comincio a capire forse cosa intendeva dire, e' vero che la
calcolatrice ha 8 (nel suo caso) cifre, ma gli esponenziali li puo'
comunque rappresentare, e quindi perche' mostra 0 anziche'
1.2246063e-16, visto che anche il suo pigreco non sara' infinitamente
preciso?

Puo' essere che anche le calcolatrici siano istruite per correggere i
casi speciali, mentre Python esegue solamente il calcolo con la
precisione che gli e' possibile.


ciao
Claudio_F
mulkrul
2010-10-08 17:40:35 UTC
Permalink
Post by Giuseppe Di Martino
Hai presente che 1.22460635382e-16 equivale a 0.000000000000000122460... ?
e che quindi visualizzando le prime 10 cifre otterrai 0 ?
Non vi è alcuna ragione per cui la mia calcolatrice debba limitarsi a visualizzare le prime 10 cifre, dal momento che
opera con i numeri in virgola mobile ed è quindi in grado di trattare numeri molto più piccoli di quello (fino a 1e-99).

Ciao
Giuseppe Di Martino
2010-10-08 18:12:36 UTC
Permalink
Post by mulkrul
Post by Giuseppe Di Martino
Hai presente che 1.22460635382e-16 equivale a
0.000000000000000122460... ? e che quindi visualizzando le prime 10
cifre otterrai 0 ?
Non vi è alcuna ragione per cui la mia calcolatrice debba limitarsi a
visualizzare le prime 10 cifre, dal momento che opera con i numeri in
virgola mobile ed è quindi in grado di trattare numeri molto più piccoli
di quello (fino a 1e-99).
Ciao
E' probabile che la calcolatrice ottimizzi i calcoli utilizzando una
tabella con valori precalcolati per alcune formule note come sin(pi), cos
(pi), etc. e quindi trovando la formula tra quelle note di dìa
direttamente 0 senza provare a calcolarlo.

Giuseppe
Enrico Franchi
2010-10-08 23:23:49 UTC
Permalink
Post by mulkrul
Di solito vengono dedicati due byte alla memorizzazione di un numero
intero per cui il maxint è 2^15=32768.

Di solito queste ingiustificate assunzioni sono alla base di simpatici
bachi.
Post by mulkrul
Mi sembra di capire che non ci sia quindi un uno spazio predeterminato per
la memorizzazione di un intero. Sbaglio?

Si chiamano "interi a precisione illimitata". Dove il limite e' la
macchina. Comodo, niente di nuovo sul fronte... in Java hai i BigNum,
uno standard de facto e' gmp (C/C++). Ci sono altre implementazioni...
ma e' roba piuttosto standard.
Post by mulkrul
Altra questione: Python introduce un sensibile errore nel calcolo di
sin(pi) che dovrebbe fare 0 (e tutte le calcolatrici che possiedo lo
calcolano correttamente).
No, non "dovrebbe" fare 0. Se lavori simbolicamente fa esattamente 0. Se
lavori con numeri macchina fa... dipende dall'algoritmo. In particolare
gli algoritmi che introducono un errore troppo grosso non si usano.

In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.

Cioe' questa "grossolanita" e' la stessa che ti puppi inconsapevolmente
da anni:

% cat sin_error.c #include <math.h> #include <stdio.h>

const double PI = 3.141592653589793;

int main() { printf("%.11le\n", sin(PI)); }

% ./sin_error 1.22464679915e-16

Mi interessa marginalmente perche' e' leggermente diverso. Avrei assunto
che Python semplicemente chiamasse sin del C.
Post by mulkrul
mi dà come risultato: 1.22460635382e-16
Vedi che sei in prossimita' dell'epsilon di macchina?

Non ci fai mica nulla. Se avessi molti algoritmi numerici il cui errore
si aggira in quell'intorno...

BTW, non vedo quale e' il problema. Tanto sanno tutti che quando si
lavora in float ci si dimentica completamente il concetto di uguaglianza
e ci si accontenta di quello di prossimita'.
Post by mulkrul
Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera e
questa "grossolanità" nei calcoli in virgola mobile?
E' colpa del computer. Se vuoi maggiore precisione, puoi usare i decimal
di python. Puoi implementarti a mano le operazione, pagando ogni bit di
precisione con il sudore della ALU della tua CPU.

<http://code.activestate.com/recipes/523018-sin-cos-tan-for-decimal/>


--
-riko
http://www.enrico-franchi.org/ http://rik0-techtemple.blogspot.com/
Enrico Franchi
2010-10-08 23:24:59 UTC
Permalink
Post by mulkrul
Di solito vengono dedicati due byte alla memorizzazione di un numero
intero per cui il maxint è 2^15=32768.

Queste assunzioni sono alla base di bachi, purtroppo.
Post by mulkrul
Mi sembra di capire che non ci sia quindi un uno spazio predeterminato per
la memorizzazione di un intero. Sbaglio?

Si chiamano "interi a precisione illimitata". Dove il limite e' la
macchina. Comodo, niente di nuovo sul fronte... in Java hai i BigNum,
uno standard de facto e' gmp (C/C++). Ci sono altre implementazioni...
ma e' roba piuttosto standard.
Post by mulkrul
Altra questione: Python introduce un sensibile errore nel calcolo di
sin(pi) che dovrebbe fare 0 (e tutte le calcolatrici che possiedo lo
calcolano correttamente).
No, non "dovrebbe" fare 0. Se lavori simbolicamente fa esattamente 0. Se
lavori con numeri macchina fa... dipende dall'algoritmo. In particolare
gli algoritmi che introducono un errore troppo grosso non si usano.

In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.

Cioe' questa "grossolanita" e' la stessa che ti puppi inconsapevolmente
da anni:

% cat sin_error.c #include <math.h> #include <stdio.h>

const double PI = 3.141592653589793;

int main() { printf("%.11le\n", sin(PI)); }

% ./sin_error 1.22464679915e-16

Mi interessa marginalmente perche' e' leggermente diverso. Avrei assunto
che Python semplicemente chiamasse sin del C.
Post by mulkrul
mi dà come risultato: 1.22460635382e-16
Vedi che sei in prossimita' dell'epsilon di macchina?

Non ci fai mica nulla. Se avessi molti algoritmi numerici il cui errore
si aggira in quell'intorno...

BTW, non vedo quale e' il problema. Tanto sanno tutti che quando si
lavora in float ci si dimentica completamente il concetto di uguaglianza
e ci si accontenta di quello di prossimita'.
Post by mulkrul
Come si conciliano questa estrema "raffinatezza" nell'aritmetica intera e
questa "grossolanità" nei calcoli in virgola mobile?
E' colpa del computer. Se vuoi maggiore precisione, puoi usare i decimal
di python. Puoi implementarti a mano le operazione, pagando ogni bit di
precisione con il sudore della ALU della tua CPU.

<http://code.activestate.com/recipes/523018-sin-cos-tan-for-decimal/>


--
-riko
http://www.enrico-franchi.org/ http://rik0-techtemple.blogspot.com/
mulkrul
2010-10-11 17:34:25 UTC
Permalink
Post by Enrico Franchi
In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.
Che significa?
Post by Enrico Franchi
Post by mulkrul
mi dà come risultato: 1.22460635382e-16
Vedi che sei in prossimita' dell'epsilon di macchina?
Intendi dire che non si può ottenere un errore assoluto inferiore all'epsilon macchina?

Grazie
Ciao
Enrico Franchi
2010-10-12 23:12:13 UTC
Permalink
Post by mulkrul
Post by Enrico Franchi
In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.
Che significa?
Quale parte non ti e' chiara?
Post by mulkrul
Post by Enrico Franchi
Post by mulkrul
mi dà come risultato: 1.22460635382e-16
Vedi che sei in prossimita' dell'epsilon di macchina?
Intendi dire che non si può ottenere un errore assoluto
inferiore all'epsilon macchina?
Intendo dire che non si puo' rappresentare un numero piu' vicino a 0 di
tale valore (dell'epsilon di macchina). Che grosso modo e' nell'ordine
di grandezza di quel numero lassu' che hai trovato. Ovvero quello la e'
un numero estremamente vicino allo 0, ma vicino vicino vicino. Pochi
numeri sono piu' vicini allo 0. Ovvero e' un buon risultato.

Di fatto sono tollerate e normali ben altre cose quando si fa calcolo
numerico.
--
-riko
http://www.enrico-franchi.org/
http://rik0-techtemple.blogspot.com/
Antonio Cuni
2010-10-13 07:46:57 UTC
Permalink
Post by Enrico Franchi
Intendo dire che non si puo' rappresentare un numero piu' vicino a 0 di
tale valore (dell'epsilon di macchina).
oddio, tecnicamente si può: 0.0 è un valore più vicino a zero dell'epsilon :-)
Post by Enrico Franchi
'%.16f' % 0.0
'0.0000000000000000'

ciao,
Anto
--
Antonio Cuni
http://morepypy.blogspot.com/
Enrico Franchi
2010-10-13 17:24:14 UTC
Permalink
Post by Antonio Cuni
oddio, tecnicamente si può: 0.0 è un valore più vicino a zero dell'epsilon :-)
'%.16f' % 0.0
'0.0000000000000000'
Oh, vero certo. Quello che intendevo e' che non si puo' rappresentare un
valore diverso da 0 piu' vicino a zero di etc etc etc. ;)
--
-riko
http://www.enrico-franchi.org/
http://rik0-techtemple.blogspot.com/
mulkrul
2010-10-13 18:54:47 UTC
Permalink
Post by Enrico Franchi
Post by mulkrul
Post by Enrico Franchi
In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.
Che significa?
Quale parte non ti e' chiara?
Non mi è chiaro il significato di "float mappati uno a uno"
Post by Enrico Franchi
Intendo dire che non si puo' rappresentare un numero piu' vicino a 0 di
tale valore (dell'epsilon di macchina). Che grosso modo e' nell'ordine
di grandezza di quel numero lassu' che hai trovato. Ovvero quello la e'
un numero estremamente vicino allo 0, ma vicino vicino vicino. Pochi
numeri sono piu' vicini allo 0.
Ho provato a sommare due numeri float enormemente più vicini allo zero dell'epsilon macchina e l'operazione è stata
Post by Enrico Franchi
Post by mulkrul
Post by Enrico Franchi
1.2e-323 + 2.3e-323
3.5e-323
Enrico Franchi
2010-10-13 19:49:57 UTC
Permalink
Post by mulkrul
Post by Enrico Franchi
Post by mulkrul
Post by Enrico Franchi
In quasi tutti i python i float seguono IEEE-754 e se anche la tua
piattaforma hardware segue quello standard, probabilmente sono mappati
uno a uno.
Che significa?
Quale parte non ti e' chiara?
Non mi è chiaro il significato di "float mappati uno a uno"
Che le operazioni floating point che fai in Pythons si appoggiano
all'aritmetica floating point della tua CPU.
Post by mulkrul
Ho provato a sommare due numeri float enormemente più
vicini allo zero dell'epsilon macchina e l'operazione è stata
Post by Enrico Franchi
Post by mulkrul
Post by Enrico Franchi
1.2e-323 + 2.3e-323
3.5e-323
Perche' ho detto io una stronzata piuttosto evidente: l'epsilon ha a che
vedere con l'errore di arrotondamento, non con il minimo numero
rappresentabile (che invece ovviamente dipende dal massimo espondente).

Ti rendi conto che quel numero e' sotto l'epsilon di macchina
sommandogli 1 e scoprendo che fa proprio 1.
Post by mulkrul
Post by Enrico Franchi
Post by mulkrul
1.2e-323 + 2.3e-323 + 1.0 == 1
True

Comunque l'idea che volevo portare avanti e' che il risultato di sin(pi)
e' appunto nell'ordine di grandezza di epsilon (cosa che confermo) e che
di conseguenza e' numericamente un buon risultato.
--
-riko
http://www.enrico-franchi.org/
http://rik0-techtemple.blogspot.com/
Loading...