« ■Office Open XML、ISO標準に・・・。 | トップページ | ☆JWWファイルの超簡易表示 その5 »

☆式の評価(数式の計算)

(0.5+2)*(8.3+2) というような式を計算します。
言語の種類を問わず数式を計算したいという質問は多いようですが、具体的なコードを見かけることが少ないため、下記書籍のコードを利用したものを載せますね。

Shiki

function Calc(S: String; var Ans: Extended): Boolean;
var
  Err : Boolean;
  P: PChar;

  procedure Error;
  begin
    Err := True;
  end;

  function Number: Extended;
  var
    X, A: Extended;
    Sign: Char;
  begin
    Result := 0;
    Sign := P^;
    if P^ in ['+','-'] then
    begin
      Sign := P^;
      Inc(P);
    end;
    if P^ in ['0'..'9'] then
    begin
      X := Ord(P^) - Ord('0');
      Inc(P);
      while P^ in ['0'..'9'] do
      begin
        X := 10 * X + Ord(P^) - Ord('0');
        Inc(P);
      end;
      if P^ ='.' then
      begin
        A := 1;
        Inc(P);
        while P^ in ['0'..'9'] do
        begin
          A := 0.1 * A;
          X := X + A * (Ord(P^) - Ord('0'));
          Inc(P);
        end;
      end;
      if Sign = '-' then
        Result := -X
      else
        Result := X;
    end
    else
      Error;
  end;

  function Expression: Extended;
  var
    X: Extended;

    function Term: Extended;
    var
      X, Y: Extended;

      function Factor: Extended;
      begin
        if P^ <> '(' then
          Result := Number
        else
        begin
          Inc(P);
          Result := Expression;
          if P^ = ')' then
            Inc(P)
          else
            Error;
        end;
      end;

    begin
      X := Factor;
      while P^ in ['*','/'] do
      if P^ = '*' then
      begin
        Inc(P);
        X := X * Factor;
      end
      else
      begin
        Inc(P);
        Y := Factor;
        if Y <> 0 then
          X := X / Y
        else
          Error;
      end;
      Result := X;
    end;

  begin
    X := Term;
    while P^ in ['+','-'] do
      case P^ of
        '+': begin
               Inc(P);
               X := X + Term;

             end;
        '-': begin
               Inc(P);
               X := X - Term;
             end;
      end;
    Result := X;
  end;

begin
  { 初期設定 }
  Ans := 0;
  Err := False;

  { 計算します。 }
  P := PChar(S);
  Ans := Expression;

  {
  計算式が、最後まで計算されたかどうかをチェック
  (制御文字等があれば途中で計算を終了するため)
  }
  if (Trim(P) <> '') then  Error;

  if Err then Ans := 0;
  Result := not Err;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Ans: Extended;
begin
  if Calc(Edit1.Text, Ans) then
    Edit2.Text := FloatToStr(Ans)
  else
    Edit2.Text := 'error';
end;

この処理は、技術評論社「コンピュータ・アルゴリズム事典」という書籍のソースコードを利用したものです。 ソースコードを利用したものを公開することについて、著者である奥村晴彦先生から許可を得ております。

奥村晴彦先生のオリジナルは、下記のリンクからダウンロードできます。
(式の評価はCHAP12.PRGに含まれています)


奥村晴彦
『コンピュータ・アルゴリズム事典』サポートページ
http://oku.edu.mie-u.ac.jp/~okumura/algo/algo_pas.html

|

« ■Office Open XML、ISO標準に・・・。 | トップページ | ☆JWWファイルの超簡易表示 その5 »