string içinde aritmetik işlem çözümleyicisi ve hesaplayıcısı

Yazdığınız makaleleri ve üyelerimizin işine yarayacağını düşündüğünüz kodlarınızı gönderebilirsiniz. Bu foruma soru sormayın!
Cevapla
Kullanıcı avatarı
husonet
Admin
Mesajlar: 2962
Kayıt: 25 Haz 2003 02:14
Konum: İstanbul
İletişim:

string içinde aritmetik işlem çözümleyicisi ve hesaplayıcısı

Mesaj gönderen husonet »

Kod: Tümünü seç

Contributor: COLIN LAMARRE

{$S-}
{$M 65520,0,655360}
{$N+}

{ Cal.pas by Colin Lamarre, 1991
  Email: lamarre@vir.com

  This program calculates a formula using recursion.

}

const
  digits : set of char = ['0'..'9', '.', 'E'];

var
  answer : extended;
  rcal : string;
  print : boolean;
  i : integer;

procedure error(cal : string; var i : integer);
begin
  if print then
  begin
    writeln(copy(cal, i - 5, 10) + ' error.');
    print := false;
  end;
  i := length(cal) + 1;
end;

function clean(var toupper : string) : boolean;
var
  i, l, r : integer;
  t : string;
begin
  print := true;
  t := '';
  l := 0;
  r := 0;
  for i := 1 to length(toupper) do
    if toupper[i] <> ' ' then
    begin
      t := t + upcase(toupper[i]);
      if toupper[i] = '(' then
        l := l + 1;
      if toupper[i] = ')' then
        r := r + 1;
    end;
  if r <> l then
  begin
    writeln('Missing brackets');
    clean := false;
  end
  else
  begin
    if t = '' then
      toupper := '0'
    else
      toupper := t;
    clean := true;
  end;
end;

function fstr(x : extended) : string;
var
  s : string;
begin
  str(x:1:9, s);
  if s[1] = ' ' then
    delete(s, 1, 1);
  fstr := s;
end;

function fval(s : string) : extended;
var
  x : extended;
  code : integer;
begin
  val(s, x, code);
  fval := x;
end;

function prevnum(var temp : string; i : integer) : extended;
var
  oldi : integer;
begin
  oldi := i;
  while ((temp[i] in digits) or ((temp[i - 1] = 'E') and (temp[i] in ['+', '-']))) and (i >= 1) do
    dec(i);
  if (temp[i] in ['+', '-']) and ((i = 1) or (temp[i - 1] in ['+', '-', '*', '/'])) then
    dec(i);
  prevnum := fval(copy(temp, i + 1, oldi - i));
  delete(temp, i + 1, oldi - i);
end;

function signs(cal : string; var i : integer) : integer;
var
  sign : integer;
begin
  sign := 1;
  repeat
    if cal[i] = '-' then
    begin
      sign := sign * -1;
      inc(i);
    end
    else
    if cal[i] = '+' then
      inc(i);
  until not(cal[i] in ['-', '+']);
  signs := sign;
end;

function nextnum(cal : string; var i : integer) : extended;
var
  temp : string;
  sign : integer;
begin
  temp := '';
  sign := signs(cal, i);
  while (cal[i] in digits) and (i <= length(cal)) do
  begin
    temp := temp + cal[i];
    inc(i);
    if (cal[i - 1] = 'E') and (cal[i] in ['+', '-']) then
    begin
      temp := temp + cal[i];
      inc(i);
    end;
  end;
  nextnum := sign * fval(temp);
end;

function getbrackets(cal : string; var i : integer) : string;
var
  count : integer;
  temp : string;
begin
  count := 1;
  temp := '';
  repeat
    inc(i);
    if cal[i] = '(' then
      count := count + 1;
    if cal[i] = ')' then
      count := count - 1;
    temp := temp + cal[i];
  until (cal[i] = ')') and (count = 0);
  delete(temp, length(temp), 1);
  inc(i);
  getbrackets := temp;
end;

function doadd(temp : string) : extended;
var
  i : integer;
  tot : extended;
begin
  i := 1;
  tot := nextnum(temp, i);
  repeat
    inc(i);
    case temp[i - 1] of
      '+' : tot := tot + nextnum(temp, i);
      '-' : tot := tot - nextnum(temp, i);
    end;
  until i > length(temp);
  doadd := tot;
end;

function domuls(cal : string) : extended;
var
  i, sign : integer;
  temp, s : string;
begin
  i := 1;
  temp := '';
  repeat
    case cal[i] of
      '+', '-' : begin
                   temp := temp + cal[i];
                   inc(i);
                 end;

      '*' : begin
              inc(i);
              sign := signs(cal, i);
              if cal[i] in digits then
              begin
                s := fstr(sign * prevnum(temp, length(temp)) * nextnum(cal,i));
                temp := temp + s;
              end
              else
              if cal[i] = '(' then
              begin
                s := fstr(sign * prevnum(temp, length(temp)) * domuls(getbrackets(cal, i)));
                temp := temp + s;
              end
              else
                error(cal, i);
            end;

      '/' : begin
              inc(i);
              sign := signs(cal, i);
              if cal[i] in digits then
              begin
                s := fstr(sign * prevnum(temp, length(temp)) / nextnum(cal, i));
                temp := temp + s;
              end
              else
              if cal[i] = '(' then
              begin
                s := fstr(prevnum(temp, length(temp)) / (sign * domuls(getbrackets(cal, i))));
                temp := temp + s;
              end
              else
                error(cal, i);
            end;

      '0'..'9', '.' : while (cal[i] in digits) and (i <= length(cal)) do
                      begin
                        temp := temp + cal[i];
                        inc(i);
                        if (cal[i - 1] = 'E') and (cal[i] in ['+', '-']) then
                        begin
                          temp := temp + cal[i];
                          inc(i);
                        end;
                      end;

      '(' : temp := temp + fstr(domuls(getbrackets(cal, i)));

      else
        error(cal, i);
    end;
  until i > length(cal);
  domuls := doadd(temp);
end;

function dopowers(cal : string) : string;
var
  i, c : integer;
  x, f : extended;

  function fcnt(var cal : string; var i : integer) : integer;
  var
    j : integer;
  begin
    j := 0;
    while cal[i] = '!' do
    begin
      inc(j);
      dec(i);
    end;
    inc(i);
    delete(cal, i, j);
    fcnt := j;
  end;

  function fact(x : extended) : extended;
  var
    k, n : word;
    ans : extended;
  begin
    ans := 1;
    if x < 0 then
      fact := ans / (x - x);
    n := trunc(x);
    for k := 2 to n do
      ans := k * ans;
    fact := ans;
  end;

  function getprev(var cal : string; var i : integer) : extended;
  var
    oldi, count : integer;
  begin
    dec(i);
    oldi := i;
    if cal[i] <> ')' then
    begin
      while ((cal[i] in digits) or ((cal[i - 1] = 'E') and (cal[i] in ['+', '-']))) and (i >= 1) do
        dec(i);
      if (cal[i] in ['+', '-']) and ((i = 1) or (cal[i - 1] in ['+', '-', '*', '/'])) then
        dec(i);
      getprev := fval(copy(cal, i + 1, oldi - i));
      delete(cal, i + 1, oldi - i);
    end
    else
    begin
      count := 1;
      while (cal[i] <> '(') and (count <> 0) and (i >= 1) do
      begin
        dec(i);
        if cal[i] = ')' then
          count := count + 1;
        if cal[i] = '(' then
          count := count - 1;
      end;
      getprev := domuls(dopowers(copy(cal, i + 1, oldi - i - 1)));
      delete(cal, i, oldi - i + 1);
      dec(i);
    end;
  end;

  function getnext(var cal : string; i : integer) : extended;
  var
    oldi, sign, count : integer;
    temp : string;
  begin
    oldi := i;
    inc(i);
    temp := '';
    sign := signs(cal, i);
    if cal[i] <> '(' then
    begin
      while (cal[i] in digits) and (i <= length(cal)) do
      begin
        temp := temp + cal[i];
        inc(i);
        if (cal[i - 1] = 'E') and (cal[i] in ['+', '-']) then
        begin
          temp := temp + cal[i];
          inc(i);
        end;
      end;
      getnext := sign * fval(temp);
      delete(cal, oldi, i - oldi);
    end
    else
    begin
      count := 1;
      temp := '';
      repeat
        inc(i);
        if cal[i] = '(' then
          count := count + 1;
        if cal[i] = ')' then
          count := count - 1;
        temp := temp + cal[i];
      until (cal[i] = ')') and (count = 0);
      delete(temp, length(temp), 1);
      getnext := sign * domuls(dopowers(temp));
      delete(cal, oldi, i - oldi + 1);
    end;
  end;

begin
  i := length(cal);
  repeat
    case cal[i] of
      '^' : begin
              x := getnext(cal, i);
              if cal[i - 1] = '!' then
              begin
                dec(i);
                c := fcnt(cal, i);
                f := getprev(cal, i);
                for c := 1 to c do
                  f := fact(f);
                insert(fstr(exp(x * ln(f))), cal, i + 1);
              end
              else
                insert(fstr(exp(x * ln(getprev(cal, i)))), cal, i + 1);
            end;

      '!' : begin
              c := fcnt(cal, i);
              f := getprev(cal, i);
              for c := 1 to c do
                f := fact(f);
              insert(fstr(f), cal, i + 1);
            end;

      else
        dec(i);
    end;
  until i < 1;
  dopowers := cal;
end;

function dofuncs(cal : string) : string;
var
  i : integer;
  temp : string;

  function next3 : string;
  begin
    next3 := cal[i + 1] + cal[i + 2] + cal[i + 3];
  end;

  function asin(ratio : extended) : extended;
  begin
    asin := arctan(ratio / sqrt((1 - ratio) * (1 + ratio)));
  end;

  function acos(ratio : extended) : extended;
  begin
    acos := arctan(sqrt((1 - ratio) * (1 + ratio)) / ratio);
  end;

  function atan(ratio : extended) : extended;
  begin
    atan := arctan(ratio);
  end;

  function tan(angle : extended) : extended;
  begin
    tan := sin(angle) / cos(angle);
  end;

  function cot(angle : extended) : extended;
  begin
    cot := cos(angle) / sin(angle);
  end;

  function log(x : extended) : extended;
  begin
    log := ln(x) / 2.302585093;
  end;

begin
  i := 1;
  temp := '';
  repeat
    case cal[i] of
      '+', '-',
      '*', '/',
      '(', ')',
      '^', '!' : begin
                   temp := temp + cal[i];
                   inc(i);
                 end;

      'S' : begin
              if next3 = 'IN(' then
              begin
                inc(i, 3);
                temp := temp + fstr(sin(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if next3 + cal[i + 4] = 'QRT(' then
              begin
                inc(i, 4);
                temp := temp + fstr(sqrt(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
                error(cal, i);
            end;

      'C' : begin
              if next3 = 'OS(' then
              begin
                inc(i, 3);
                temp := temp + fstr(cos(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if next3 = 'OT(' then
              begin
                inc(i, 3);
                temp := temp + fstr(cot(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
                error(cal, i);
            end;

      'T' : begin
              if next3 = 'AN(' then
              begin
                inc(i, 3);
                temp := temp + fstr(tan(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
                error(cal, i);
            end;

      'A' : begin
              if next3 + cal[i + 4] = 'TAN(' then
              begin
                inc(i, 4);
                temp := temp + fstr(atan(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if next3 + cal[i + 4] = 'COS(' then
              begin
                inc(i, 4);
                temp := temp + fstr(acos(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if next3 + cal[i + 4] = 'SIN(' then
              begin
                inc(i, 4);
                temp := temp + fstr(asin(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if next3 = 'BS(' then
              begin
                inc(i, 3);
                temp := temp + fstr(abs(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
                error(cal, i);
            end;

      'L' : begin
              if next3 = 'OG(' then
              begin
                inc(i, 3);
                temp := temp + fstr(log(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
              if cal[i + 1] + cal[i + 2] = 'N(' then
              begin
                inc(i, 2);
                temp := temp + fstr(ln(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
              end
              else
                error(cal, i);
            end;

      'E' : if next3 = 'XP(' then
            begin
              inc(i, 3);
              temp := temp + fstr(exp(domuls(dopowers(dofuncs(getbrackets(cal, i))))));
            end;

      'P' : if cal[i + 1] = 'I' then
            begin
              inc(i, 2);
              temp := temp + fstr(pi);
            end
            else
              error(cal, i);

      '0'..'9', '.' : while (cal[i] in digits) and (i <= length(cal)) do
                      begin
                        temp := temp + cal[i];
                        inc(i);
                        if (cal[i - 1] = 'E') and (cal[i] in ['+', '-']) then
                        begin
                          temp := temp + cal[i];
                          inc(i);
                        end;
                      end;

      else
        error(cal, i);
    end;
  until i > length(cal);
  dofuncs := temp;
end;

begin
  rcal := '';
  for i := 1 to paramcount do
    rcal := rcal + paramstr(i);

  if clean(rcal) then
  begin
    answer := domuls(dopowers(dofuncs(rcal)));
    if print then
      writeln(answer:1:9);
  end;

end.
Kolay Gelsin...

Gazete manşetleri
* DİKKAT :Lütfen forum kurallarını okuyalım ve uyalım...!
* Warez,crack vs. paylaşımı kesinlikle yasaktır.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

Nereden buldun helal olsun.. Google taraması yaptım bulduğunu sandığım yerde bir sürü inci var.

http://www.bsdg.org/SWAG/MATH/index.html

Neyse konuyu dağıtmayım, Excel'den de teyid ettim. Test için verdiğim şu formül

Kod: Tümünü seç

  Formul := '10*2+23-4/2^3';
42.50 çıkıyor.

Güzel de çalışıyor... :o
Resim
Resim ....Resim
Kullanıcı avatarı
husonet
Admin
Mesajlar: 2962
Kayıt: 25 Haz 2003 02:14
Konum: İstanbul
İletişim:

Mesaj gönderen husonet »

mrmarman yazdı:Nereden buldun helal olsun.. Google taraması yaptım bulduğunu sandığım yerde bir sürü inci var.

http://www.bsdg.org/SWAG/MATH/index.html

Neyse konuyu dağıtmayım, Excel'den de teyid ettim. Test için verdiğim şu formül

Kod: Tümünü seç

  Formul := '10*2+23-4/2^3';
42.50 çıkıyor.

Güzel de çalışıyor... :o
Abi baya önce bulmuştum :) HusoEditCalc tada kullanmıştım evet mükemmel çlışıyor :) Umarım faydalanırsınız abi benim bir çok işime yarıyor. :)

Gazete manşetleri
* DİKKAT :Lütfen forum kurallarını okuyalım ve uyalım...!
* Warez,crack vs. paylaşımı kesinlikle yasaktır.
SieS
Üye
Mesajlar: 166
Kayıt: 17 Haz 2003 10:41
Konum: Konya

Mesaj gönderen SieS »

Çok güzel hocam teşekkürler, peki değişkenlerle denedinizmi hiç,
mesela
C= a *b / z
bunu apabiliyorsak çok güzel şeyler çıkar ortaya..

Teşekkürler..
Ben Toprağın Sinesinde İnsan Denilen Bir Canım
Hem Düşünür, Hem Severim Budur Taştan Faklı Yanım.
Her maddenin zevlesini bedenimde taşıyorsam.
Ben ne bir taş ne bir ağaç, insanlığımla insanım.
ssteeltr
Üye
Mesajlar: 135
Kayıt: 08 Nis 2005 03:41
Konum: Kayseri

Mesaj gönderen ssteeltr »

Arkadaşlar birde unu delphi içinde nasıl kullanacam bi örnekleseniz
Süleyman Çelik
Cevapla