Newsgroup: it.comp.lang.delphi
Titolo: ora m'incazzo!

ragazzi, sto veramente sclerando!!
la questione e' questa:
VAR a,b:Double;
begin
  a:=8.8;
  b:=8.8;
  while a<=b do
  [...]
ebbene, (a<=b) mi da' FALSE!!
intendo dire che secondo delphi1 (8.8<=8.8) e' FALSE!!!!
ma che cazzo diceeeeEEEEEEEEEEEEEE!?!?!?!?!?!?!
e non e' finita, se debuggo e vado con una evaluate del tipo
a<b  mi dice FALSE
a=b  mi dice FALSE
a>b  mi dice TRUE
ma come? 8.8 sarebbe maggiore di 8.8 ???
beh cosa diavolo succede?
scusate il linguaggio! ma proprio sto diventando scemo!
Sent via Deja.com 
http://www.deja.com/
Before you buy.

dunque non vorrei dire una cavolata enorme, ma sentite qua:
Il tipo REAL č una rappresentazione dei numeri reali. I numeri reali per la
loro natura sono "densi" cioč presi due a caso ce ne č sempre uno in mezzo.
Ora naturalmente non č possibile rappresentare esattamente questa situazione
per cui ci sono i real, che la approssimano. Essi constano se non vado
errato di una mantissa e di un esponente, permettendo cosě una precisione
maggiore tanto č piccolo il numero. Funziona piů o meno come le
calcolatrici.
 Il problema č che a volte l'approssimazione sbaglia di un pochino e vengono
fuori questi errori
Questo č quello che mi ha spiegato il mio prof di c++, se č una cavolata
prendetevela con lui :)
Ciao !            {MSX}


prova a limitare il numero di decimali.
Ad esempio, se te ne servonno 2, crea una variabili long (una per variabile
double)  che abbiano come valore l'intero della double di riferimento*100.
Poi fai il confronto e vedi quello che succede.
Saluti
AS

Certo la soluzione più ovvia è quella di separare parte intera e parte
decimale e moltiplicare quest'ultima per un fattore piu o meno grande in
base alla precisione che si vuole ottenere, ma non mi sembra il caso di
dover agire sempre in questo modo avendo poi sotto un super Ambiente di
sviluppo ed un mega processore con una specie di "sistema operativo" che lo
fa lavorare.
Naturalmente la cosa mi ha fortemente incuriosito ed ho iniziato a provare
sia questo caso che il mio, esposto qualche domanda più giù («E' un bug
conosciuto o cosa?»), i risultati sono stati:
MS DOS, Windows NT, Windows X.x, Mac OS si comportano in maniera uguale;
sono passato a provare un po' di applicazioni: Excel sbaglia dal 4 in su,
Lotus 123 dal 1,000... non ricordo più cosa, Delphi & VB come se la cosa a
loro non interessasse (i dati di debug riportano i giusti valori, ma le
comparazioni non fungono), FileMaker inizia a dire cavolate dal 9 in su.
Insomma in un mondo informatizzato dove ci spaventiamo del Millennium Bug,
dobbiamo ricorrere quasi alla carta per fare un semplice confronto senza
richiedere grosse precisioni (voglio dire 0.1 non 0.0000000000000001 non so
se...) le quali giustificherebbero i problemi di rappresentazione indicati
da qualcuno e chissà quali programmi non hanno avuto l'accortezza di
verificare questa situazione e oggi lo usa per fare quadrature di bilanci o
qualcos'altro d'importante.
In effetti anch'io sono tra il deluso e l'incazzato per l'essermi trovato
questo macigno tra capo e collo e non averne mai sentito parlare, neanche
sotto il punto di vista di investimenti per evitare, come per il Millennium
Bug, ancora il perdurare di questa...favoletta!!
Evviva la scienza ESATTA : l'Informatica e l'Elettronica.
Ciao..............Francesco. :-|
P.S.
  A questo punto chissà cos'altro ci aspetta ancora...

 a>b  mi dice TRUE
Non sono riuscito a riprodurre il problema con Delphi 5. E mi pare strano
che si verifichi anche con Delphi 1. Qui non puo' essere la solita faccenda
che i valori reali sono approssimati. Qui si tratta dello stesso valore
memorizzato in due variabili dello stesso tipo.
Che cosa ci hai messo al posto di [...]?
Dove la fai la evaluate?
Potresti darci un po' piu' di codifica? Sarebbe bene una procedurina
completa che evidenzi il problema, da potersi copiare e provare.

Tieni presente che per le operazioni contabili usare i real e' da suicidio.
Esiste il tipo currency apposta, che NON approssima i decimali ma li
rappresenta cifra per cifra; in questo modo le operazioni sono esatte.
Ciao, Sandro


ok gente, ho risolto!
grande {msx}! era proprio quello!
me ne sono accorto piu o meno mentre a luna rossa e' finito lo spin
sotto la chiglia. notte insonne! ma non per luna rossa (chi se ne
frega), e' che dovevo sistemare il problema entro questa mattina!
comunque quello che facevo, piu esattamente, era questo:
############################
var mioDouble:double;
    mioReal:Real;
begin
   mioDoube:= table1.fieldbyname('CAMPO1').AsFloat; // 8.8 appunto!
   mioReal := table1.fieldbyname('CAMPO1').AsFloat; // stesso valore!!!!
   while mioReal=mioDouble do
   [...]
############################
ed infatti, come dice msx, "mioReal" contiene un valore diverso da
"mioDouble", nonostante io gli abbia assegnato lo stesso valore.
grazie a tutti. scusate di nuovo l'incazzatura e le espressioni poco
raffinate ma stavo proprio con l'acqua (e le mani del cliente) alla
gola.





si vabbe' ...c'era da andare a capo,
ecche sara' mai, tanto si
capiva lo stesso no?
############################
 var mioDouble:double;
     mioReal:Real;
 begin
     mioDoube:= table1.fieldbyname('CAMPO1').AsFloat; // 8.8 appunto!
     mioReal := table1.fieldbyname('CAMPO1').AsFloat;
     while mioReal=mioDouble do
     [...]



Forse ho pescato giusto l'argomento di esempio sbagliato, ma cio non toglie
che č "poco corretto" quanto succede e, sottolineo, non solo con Delphi,
come le mie prove hanno dimostrato. Bella fregatura sapere di avere una
specie di Bug a livello hardware (a quanto ho capito) e che nessuno mi sa si
stia dando da fare per correggerlo. Questa cosa fa sembrare l'Y2K Bug un
videogame.
P.S. Scusate se me la prendo cosě tanto con il bug del millennio, ma l'ho
sempre visto come una enorme trovata commerciale, esclusi i casi conclamati
naturalmente.
Ciao............Francesco.   :-)

 trattava sempre di tipi leggermente diversi (es: extended vs. double).
gia, scusate!
in effetti io usavo 2 var differenti e, nell'esempio, per praticitita'
le ho dichiarate uguali.
il fatto e' che nel codice "vero" i valori che assegno
alle 2 variabili "a" e "b" (che sono entrambe double),
provenivano da variabili di diverso tipo, a seconda dei casi.
e ora, vi riposto il codice, con la modifica per la verifica
dell'anomalia, che si verifica con delphi 1 e 3, ma non con d5:
---------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
VAR a,b:Double;
    X :real;
begin
   a := 8.8 ; // DOUBLE
   X := 8.8 ; // REAL
   b := X ;   // DOUBLE
   if a=b
   then showmessage('a=b True')
   else showmessage('a=b False')
end;



Che e' completamente diverso da quello che hai scritto prima.
La prossima volta evita le semplificazioni troppo spinte cosi' rendi +
facili e precise le risposte
Ciao,
Stefano

 dell'anomalia, che si verifica con delphi 1 e 3, ma non con d5:
E' improprio che tu usi la parola "anomalia". Se tu memorizzi uno stesso
valore in due variabili reali ma di tipi diversi, e' assolutamente normale
che tu ottenga valori approssimati diversi, per lo stesso motivo per cui
0.6667 e' diverso da 0.666666666667.
Per certi valori, per certe combinazioni dei due tipi di variabili e per
certe versioni di Delphi puoi anche ottenere valori uguali, ma in genere
questo non avviene e non puo' avvenire.


gia! me ne sono accorto.
ciao, dennis.


 e se delphi mi dice che non lo sono allora come la devo chiamare?
La puoi chiamare illusione ottica dovuta al formato utilizzato dal watch per
mostrati il valore. Con Delphi 5 puoi mostrare il watch in modalita' memory
dump. E allora vedi esattamente che cosa c'e' in memoria, e cio' che appare
uguale nel watch sara' anche uguale per il programma. Con le altre versioni
di Delphi non ricordo.
Bada che in Delphi 5 pare che il problema non si verifichi perche' Real e'
sinonimo di Double. Se provi con una variabile Single e l'altra Double avrai
ancora lo stesso problema.

 wrote in message
87elpj$g5i$1...@serv1.iunet.it...


la variabile a rispetto a b ...
Si hai ragione.. ma come si vede da un post successivo,  dennis , non faceva
proprio un assegnamento uguale. Che tu ci creda o no, l'avevo intuito (sarň
veggente ? :)
Piů che intuito, non avevo capito come era possibile il suo problema, cosě
il mio misero cervello ha trovato la soluzione piů plausibile..
Ciao !                {MSX}




 i registri della cpu...:-)
magari while abs(a-b) < epsilon do .........