Newsgroup: it.comp.lang.visual-basic
Titolo: [?]Calcolatrice tipo RPN

So che forse l'argomento non è proprio inerente a questo newsgroup ma devo
progettare una calcolatrice di tipo RPN, qualcuno di voi sa dirmi
esattamente come caspita funziona, o dove reperire informazioni utili?
Fino ad oggi vi ho spedito un paio di quesiti che hanno sempre trovato
risposte molto precise e chiare, speriamo saprete rispondere anche a questa.
Trovo il newsgroup molto interessante e utile e proprio non capisco quelli
che si lamentano o addirittura si incazzano vedi 'lava' con 'Grazie a tutti
i deficenti' che poi si scrive deficienti con la 'i' ;-)))))
Vi ringrazio in anticipo

Apro una parentesi: sono d'accordo con te sulla questione indicata
qui sotto...
Micio


risposte molto precise e chiare, speriamo saprete rispondere anche a
questa.


Ti do qualche dritta, ma ti consiglio di procurarti un manuale di
qualche calcolatrice Hewlett-Packard, per capire meglio come strutturare
il programma. Prova sul sito di HP.
La RPN, Notazione Polacca Inversa, è basata sull'utilizzo di uno stack
LIFO (Last In First Out) di operandi che tempo fa, nell'implementazione
di base della Hewlett-Packard su calcolatrici e calcolatori
programmabili (per intenderci, l'HP67/97, HP41C/X/CX, HP10C, HP11C,
HP15C) contemplava quattro registri più un quinto registro che
memorizzava costantemente l'ultimo operatore immesso (Last X). Lo stack,
però, può avere dimensioni maggiori, anche se con quattro registri si fa
veramente di tutto. Gli operatori *seguono* l'introduzione degli
operandi, e ogni operazione genera uno scorrimento verso il basso dello
stack, con duplicazione automatica dei valori presenti nel registro più
alto.
Non è presente il tasto "=", in quanto l'operazione viene eseguita alla
pressione del tasto dell'operatore. E' invece presente un tasto di tipo
"Enter", che è l'operatore di input dei dati nello Stack. Enter genera
lo scorrimento verso l'alto dell'operando, duplicandone il valore nel
registro x.
Chiamiamo x il registro normalmente visualizzato sul display, y,z,t gli
altri registri (generalmente non visibili). Lo stack, o "catasta" ha lo
schema seguente:
t [     0,00]
z [     0,00]
y [     0,00]
x [     0,00] (Display)
Introducento un operando si occupa il registro x:
 
t [     0,00]
z [     0,00]
y [     0,00]
x [      321]
premendo Enter si fa scorrere la catasta, duplicando l'operando in x:
t [     0,00]
z [     0,00]
y [   321,00]
x [   321,00]
Nota: premendo ripetutamente Enter, si eseguono ripetuti scorrimenti in
alto eduplicazioni di x.
Introducendo un secondo operando, si sovrascrive x:
t [     0,00]
z [     0,00]
y [   321,00]
x [      123]
premendo Enter e introducendo un terzo operando...
t [     0,00]
z [   321,00]
y [   123,00]
x [      111]
Introducendo l'operatore (in questo caso "+") si ottiene:
t [     0,00] 'Valore z duplicato
z [     0,00] 
y [   321,00] 'ex reg. z 
x [   234,00] 'Risultato di x+y
con uno scorrimento in basso dello stack e il reg. LastX [   111,00].
Introducendo nuovamente l'operatore "+" si ottiene:
t [     0,00]
z [     0,00]
y [     0,00]
x [   555,00] 'Risultato di x+y
LastX [   234,00]
A questo punto, l'introduzione di un nuovo operando non necessita di
Enter: l'input di operandi appena dopo un'operazione genera
automaticamente lo scorrimento. In pratica, questo avviene fin
dall'inizio, solo che non è evidente, dato che lo stack è pieno di zeri,
e l'introduzione di un operando provoca lo scorrimento dello zero da x a
y, con un nulla di fatto, alla nostra vista.
La duplicazione automatica di t (cioè della coda) fa sì che una sequenza
di tipo:
"3" Enter Enter Enter + + + + + + + + + ...
continui a sommare uno al risultato, come succede nelle normali
calcolatrici, premendo ripetutamente "=". I primi tre Enter spingono x
("3") fino in cima, dopo di che la cima verrà duplicata ad ogni
scorrimento in basso dovuto ad un'operazione, riempiendo costantemente
la catasta di "3" Però non in tutte le calcolatrici è implementata la
duplicazione della coda. Credo principalmente perché ha senso solo se i
registri sono in numero molto limitato. Nell'HP28, per esempio, i
registri sono limitati solo dalla memoria: che ti duplico? il 2345esimo
registro? :-)
Ma il vantaggio principale sta nel fatto che non c'è bisogno di
parentesi (che ti guarderai dall'implementare nel tuo prg :-)), e si ha
un approccio più "aritmetically correct" :-) nella risoluzione di
espressioni complesse. Si parte, infatti, sempre dall'operazione più
interna, e non c'è mai bisogno di memorizzare alcunché manualmente.
Tutto il lavoro è svolto dallo stack automatico, e non ci sono memorie
di tipo M+, M-, etc. (orribili). Ogni volta in cui un valore deve essere
serbato per una operazione con un'espressione ancora da calcolare, è
sufficiente "dimenticarselo" nello stack e procedere all'input e alle
operazioni richieste dall'espressione. Il valore della prima parte
"galleggerà" costantemente sopra tutti gli altri operandi e risultati
intermedi, e alla fine ci troveremo con il primo risultato in y e il
secondo in x. Basterà introdurre l'operando adatto e il gioco è fatto.
Niente memorie né parentesi.
E il gioco diventa divertente quando l'operazione da eseguire è, per
esempio, un'elevazione a potenza: dovendo elevare il risultato di
un'espressione, poiché senza uso di parentesi si arriva ad avere nello
stack, base e esponente, e l'operatore arriva per ultimo. Possiamo anche
decidere all'ultimo di cambiare operatore... 
Es:
 {[a + b * (c + d/e)] / (f + g)} ^ (h + i/j)
si risolve con:
 d [Enter] e [:] c [+] b [*] a [+]
 f [Enter] g [+]
 [/]
 i [Enter] j [/] h [+]
 [Y^x]
Il secondo Enter ha l'effetto di spostare anche il primo valore parziale
fuori dal campo di intervento degli operatori (fra x e y) e iniziare
quindi il calcolo di un nuovo valore intermedio, mentre il primo
"galleggia" indisturbato. Subito dopo, un [/] esegue il quoziente fra i
due parziali. Si ottiene un nuovo parziale, reso "galleggiante" dal
terzo Enter, in attesa di trovarsi a quattr'occhi con  il prossimo
parziale, l'esponente. Avremo, infatti, in y la base, che aveva
"galleggiato", e in x l'esponente. L'operatore di elevamento di y a x ci
dona il risultato. Sempre partire dall'interno...
Gli operatori a due operandi si inseriscono sempre tra i valori x e y.
Gli operatori mono-operando agiscono sul registro x senza scorrimenti
della catasta, e restituendo il risultato sempre in x.
Ci sono alcuni operatori comuni sullo stack (oltre al necessario Enter
che sono lo scambio di x con y (utile quando l'ordine è essenziale, come
in sottrazioni, divisioni e potenze), il richiamo di LastX, lo
scorrimento in alto e in basso (forzato, a rotazione) dello stack,
l'eliminazione (drop) del valore Last In (come togliere elementi ad una
catasta dal di sotto)
Sembra contorto, ma una volta imparato il meccanismo non lo si lascia
più, e i calcoli sono molto più spediti.
Spero di non averti confuso le idee :-)
Flavio Ronco
-- 
f.ronco@*NonMiServeNiente*
flashnet.it
http://www.metabrains.com
  [Under Construction]
-------------------------------------------------------------
"Che pubblico in gamba! Se ci dite dove lavorate,
domani mattina se abbiamo tempo vi veniamo a vedere"
[Paolo Rossi]


Mi collego al tuo escursus solamente per ricordare che l'hp28s è stata (io
la uso ancora e la trovo ineguagliabile) uno dei migliori calcolatori
tascabili programmabili della storia.
PS: con la pressione del tasto enter, nell'hp28 viene duplicato solo
l'ultimo dato  dello stack.
Ciao Marco