Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Delphi - Valore di ritorno errato
Forum - Delphi - Valore di ritorno errato

Avatar
lorenzo (Normal User)
Guru


Messaggi: 1178
Iscritto: 15/04/2008

Segnala al moderatore
Postato alle 10:47
Sabato, 17/10/2009
Ragazzi, da due giorni sto impazzendo su un pezzo di codice e non capisco cosa non va...allora si tratta di una classe incaricata di trasformare una stringa del tipo "3+2*4" nel suo reale valore calcolato(11 quindi)

ecco il codice:

Codice sorgente - presumibilmente Delphi

  1. unit Unit5;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, contnrs, Math, Dialogs;
  9.  
  10. type
  11.  
  12.   PInt = ^Integer;
  13.   { RPNCreator }
  14.  
  15.   RPNCreator = class
  16.   private
  17.     operatori: TStack;
  18.     operandi: TStack;
  19.     value: String;
  20.     function IsOperator(c: Char): Boolean;
  21.     function Precedence(n1, n2: Char): Integer;
  22.     procedure ReduceOperator;
  23.     function InfixToPostfix: Double;
  24.   public
  25.     constructor Create(v: String);
  26.     function Calculate: Double;
  27.   end;
  28.  
  29. implementation
  30.  
  31. { RPNCreator }
  32.  
  33. constructor RPNCreator.Create(v: String);
  34. begin
  35.   operatori := TStack.Create;
  36.   operandi := Tstack.Create;
  37.   value := v;    //la stringa che contiene la funzione da calcolare
  38. end;
  39.  
  40. function RPNCreator.Calculate: Double;
  41. begin
  42.   Result := InfixToPostfix;
  43. end;
  44.  
  45. function RPNCreator.IsOperator(c: Char): Boolean;
  46. begin
  47.   case c of
  48.   '+', '-', '*', '/', '^': Result := True;
  49.   else
  50.     Result := False;
  51.   end;
  52. end;
  53.  
  54. function RPNCreator.Precedence(n1, n2: Char): Integer;
  55. var
  56.   a, b: Integer;
  57. begin
  58.   case n1 of
  59.     '(': a := 4;
  60.     '^': a := 3;
  61.     '*', '/': a := 2;
  62.     '+', '-': a := 1;
  63.     else
  64.       a := 0;
  65.   end;
  66.  
  67.   case n2 of
  68.     '(': b := 4;
  69.     '^': b := 3;
  70.     '*', '/': b := 2;
  71.     '+', '-': b := 1;
  72.     else
  73.       b := 0;
  74.   end;
  75.  
  76.   Result := a - b;
  77. end;
  78.  
  79. procedure RPNCreator.ReduceOperator;
  80. var
  81.   opCurr: Char;
  82.   a, b: Double;
  83.   ris: PDouble;
  84. begin
  85.   opCurr := Char(operatori.Pop^);
  86.   case opCurr of
  87.     '*':
  88.     begin
  89.       a := Double(operandi.Pop^);
  90.       b := Double(operandi.Pop^);
  91.       New(ris);
  92.       ris^ := a * b;
  93.       operandi.Push(ris);
  94.     end;
  95.     '/':
  96.     begin
  97.       a := Double(operandi.Pop^);
  98.       b := Double(operandi.Pop^);
  99.       New(ris);
  100.       ris^ := a / b;
  101.       operandi.Push(ris);
  102.     end;
  103.     '+':
  104.     begin
  105.       a := Double(operandi.Pop^);
  106.       b := Double(operandi.Pop^);
  107.       New(ris);
  108.       ris^ := a + b;
  109.       operandi.Push(ris);
  110.     end;
  111.     '-':
  112.     begin
  113.       a := Double(operandi.Pop^);
  114.       b := Double(operandi.Pop^);
  115.       New(ris);
  116.       ris^ := a - b;
  117.       operandi.Push(ris);
  118.     end;
  119.     '^':
  120.     begin
  121.       a := Double(operandi.Pop^);
  122.       b := Double(operandi.Pop^);
  123.       New(ris);
  124.       ris^ := Power(a, b);
  125.       operandi.Push(ris);
  126.     end;
  127.   end;
  128. end;
  129.  
  130. function RPNCreator.InfixToPostfix: Double;
  131. var
  132.   i, aux: Integer;
  133.   c, s: Char;
  134.   n: PInt;
  135. begin
  136.   i := 1;
  137.   value := Trim(value);
  138.   while i < Length(value) do
  139.   begin
  140.     if value[i] = ')' then
  141.     begin
  142.       while Char(operatori.Peek^) <> '(' do
  143.       begin
  144.         ReduceOperator;
  145.       end;
  146.       operatori.Pop;
  147.     end;
  148.     if value[i] = '(' then
  149.       operatori.Push(@value[i])
  150.     else
  151.       if IsOperator(value[i]) then
  152.       begin
  153.         if Precedence(Char(operatori.Peek^), value[i]) < 0 then
  154.           operatori.Push(@value[i])
  155.         else
  156.         begin
  157.           ReduceOperator;
  158.           operatori.Push(@value[i]);
  159.         end;
  160.       end
  161.       else //è un numero, vediamo se è a più cifre
  162.       begin
  163.         New(n);
  164.         n^ := 0;
  165.         while TryStrToInt(value[i], aux) do
  166.         begin
  167.           n^ := n^ * 10;
  168.           n^ := n^ + aux;
  169.           Inc(i);
  170.         end;
  171.         operandi.Push(n);
  172.       end;
  173.       Inc(i);
  174.   end;
  175.   while operatori.Count > 0 do
  176.     ReduceOperator;
  177.   Result := Double(operandi.Peek^);
  178. end;
  179.  
  180. end.



è ancora un inizio e non è completo ma la parte che non funziona è la gestione dei numeri(vedi commento).
Allora, l'algoritmo termina correttamente e nella variabile puntatore "n" che poi inserisco nello stack ci trovo il valore corretto. Il problema è che quando faccio la Peek(o la Pop, è uguale) per ritornare il valore, mi trovo come risultato 2.4234364736e-34 cioè un numero a caso.

Perché questo???

ps: non è Delphi ma lazarus, comunque è lo stesso:k:

PM Quote
Avatar
lorenzo (Normal User)
Guru


Messaggi: 1178
Iscritto: 15/04/2008

Segnala al moderatore
Postato alle 20:36
Lunedì, 19/10/2009
c'é nessunooooo? :D

PM Quote