PDA

Visualizza la versione completa : [PASCAL] Istruzione "case...of" non supporta l'operatore ">"


Rising1
19-02-2011, 22:25
Ciao a tutti, è questo il mio primo topic :D
ho iniziato da poco a studiare pascal per diletto, ma ho un problema con questo programma che deve risolvere una equazione di 2°grado

program equazione;
uses crt;
var a , b , c , D , x1 , x2 : real;
begin
CLRSCR;
writeln ('l equazione deve essere in forma normale');
writeln ('inserire il valore di a ');
read(a);
writeln('di b ');
read(b);
writeln('e di c ');
read(c);
D:=b^2-4*a*c;
end.
è incompleto ovviamente
ma il ciclo

CASE D OF
>0:
etc
0:
etc
else
writeln('equazione impossibile')
il compilatore lo rifiuta per quel >5, come posso fare altrimenti?
(se minore di zero compare equazione impossibile, altrimenti risolve

sebaldar
19-02-2011, 23:16
devi usare




if D > 0 then begin
...
end
else if D = 0 then begin
...
end
else begin
...
end;

deleted_29
20-02-2011, 11:41
non è opportuno fare confronti (per stabilità numerica) tra numeri reali.

Devi stabilire un eps (il tuo "zero"), stabilire una norma (=distanza) e fare i confronti con [prediamone una semplice] ABS(valore) > eps.

Meglio ancora la norma quadratica (valore*valore), che non soffre della discontinuità, ma ne puoi "inventare" quante ne vuoi (a seconda delle circostanze).

Rising1
20-02-2011, 19:27
Originariamente inviato da franzauker
non è opportuno fare confronti (per stabilità numerica) tra numeri reali.

Devi stabilire un eps (il tuo "zero"), stabilire una norma (=distanza) e fare i confronti con [prediamone una semplice] ABS(valore) > eps.

Meglio ancora la norma quadratica (valore*valore), che non soffre della discontinuità, ma ne puoi "inventare" quante ne vuoi (a seconda delle circostanze).

ehh? no aspetta ti ringrazio perchè so che (se avessi capito) la tua risposta è molto precisa ed accurata, ma siccome sono appena entrato nel mondo di pascal (tra l'altro come autodidatta perchè nonostante in un pni, non faccio informatica :dhò: ) potresti spiegarlo in parole povere perchè devo usare if..than e non case of (come tra l'altro a giustamente detto sebaldar)?
grazie ;)

comincio a capire, ma come faccio ad impostare questo "mio 0"?

deleted_29
20-02-2011, 19:46
Originariamente inviato da Rising1
ehh? no aspetta ti ringrazio perchè so che (se avessi capito) la tua risposta è molto precisa ed accurata, ma siccome sono appena entrato nel mondo di pascal (tra l'altro come autodidatta perchè nonostante in un pni, non faccio informatica :dhò: ) potresti spiegarlo in parole povere perchè devo usare if..than e non case of (come tra l'altro a giustamente detto sebaldar)?
grazie ;)
vabbè non ho le basi, dovrai accontentarti delle altezze :spy:
---

I numeri in virgola mobile sono rappresentati internamente (dalla CPU/FPU) mediante numeri discreti (binari) (* ciò non è sempre vero, dipende dal tipo di processore, ma lasciamo stare)

Questo significa che NON esistono, in realtà, in numeri reali dentro un elaboratore digitale (in uno analogico sì, ma lasciamo stare).

Questo determina tutta una caterva di effetti collaterali denominati (genericamente) stabilità, ossia la possibilità che gli effetti di arrotondamento (inevitabilmente introdotti) si "accumulino" man mano, fino a diventare talmente grandi da provocare guai.

Questo capita ad esempio sottraendo due numeri molto piccoli e simili e così via (*la faccio breve)
---
Ciò che accade è che tu pensi, ad esempio, di aver a che fare con uno zero (0), mentre la rappresentazione interna è qualcosa del tipo 0.000000000234 (*la faccio breve)

Il perchè ciò accada è lungo da spiegare, spero che ti accontenti dei cenni.

Nel tuo caso non è opportuno quindi fare una verifica
"tot"=0, perchè abbiamo detto che potrebbe soffrire di instabilità: 0.000000000234 è diverso da zero (dal punto di vista del computer), ma non dal tuo.

Devi stabilire quale sia il tuo "zero" fissando una soglia, ad esempio 0.001 (detto normalmente eps o epsilon, o numero più piccolo che puoi distinguere), e stabilire che un intorno (con una metrica opportuna) del punto sia indistinguibile dal punto stesso.

In sintesi il test può essere "se valore <=0.001 allora lo considero zero".

Ma ti serve anche il caso di instabilità sul segno, ossia che diventi negativo (il numero, tipo -0.000000000234).

Quindi "se valore<=0.001" O "valore >=-0.001" allora lo considero zero.

Puoi "fondere" i test mettendo un "valore assoluto": "se il valore assoluto di X è <=0.001 lo considero zero"

Per inciso il "valore assoluto" introduce un problema (ecco perchè canonicamente si usa norma2 * la faccio breve), ossia è una funzione non continua.

Diciamo quindi che nel "mondo reale" useresti qualcosa "se il valore del QUADRATO di X è <= di qualcos'altro, allora lo considero zero".

Facendo il QUADRATO ottieni un numero positivo, e la funzione "quadrato" è "bella" (* la sto facendo veramente breve)

---
Superriassunto: se hai variabili INTERE puoi usare =, se hai variabili REALI devi (dovresti) usare sempre <=, >=, <, > e NON uguale

Loading