В общем можно забивать любые правильные* арифметические выражения и получать результат их вычисления
*правильные - т.е. выражение может состоять только из чисел, разделитель десятичной части - точка, скобок, и бинарных операций +-*/
унарный минус также приветствуется: выражение -3*(5/-2) = -3*(-2.5) = +7.5.
вот 4 примера возможных выражений (приведены как тест):
Цитата
ex1 := '10*(5+2*(1-3))';                      { +10   }
ex2 := '(-1+(5/2)+3+4+5/2--1*5)'; { +16 }
ex3 := '-2*(2+3)*4+(2*2+1+-5/2)*2+(2*(6/3))'; { -31 }
ex4 := '1*10*100+((0*81))+0.5+(((0.5)))'; { +1001 }
ex2 := '(-1+(5/2)+3+4+5/2--1*5)'; { +16 }
ex3 := '-2*(2+3)*4+(2*2+1+-5/2)*2+(2*(6/3))'; { -31 }
ex4 := '1*10*100+((0*81))+0.5+(((0.5)))'; { +1001 }
просьба сообщать о найденных багах.
ps в выражение записывать нужно без пробелов. Правильность выражения и баланс скобок не проверяются (пока)
{$N+}
program _SmartCalc;
uses crt;
type
  TFloat = Single;
  TOperands = array [1..128] of TFloat;
  TOperations = array [1..127] of Char;
function FloatToStr(const fValue: TFloat): String;
var
  sValue: String;
begin
  Str(fValue:0:2, sValue); FloatToStr := sValue;
end;
function StrToFloat(const sValue: String): TFloat;
var
  fValue: TFloat;
  err: Integer;
begin
  Val(sValue, fValue, err); StrToFloat := fValue;
end;
function AtomExpr(const operand_a, operand_b: TFloat;
 const operation: Char): TFloat;
begin
  case operation of
    '+': AtomExpr := operand_a + operand_b;
    '-': AtomExpr := operand_a - operand_b;
    '*': AtomExpr := operand_a * operand_b;
    '/': AtomExpr := operand_a / operand_b; 
  end;
end;
procedure SimplifyExpr(var operands: TOperands;
 var operations: TOperations; var opnds_count, optns_count: Byte);
var
  i, j: Byte;
begin
  i := 1;
  while i <= optns_count do begin
    if operations[i] in ['*', '/'] then begin
      operands[i] :=
       AtomExpr(operands[i], operands[i + 1], operations[i]);
      for j := i + 1 to opnds_count - 1 do
       operands[j] := operands[j + 1];
      dec(opnds_count);
      for j := i to optns_count - 1 do
       operations[j] := operations[j + 1];
      dec(optns_count);
    end
      else inc(i);
  end;
end;
function SubExpr(const s: String): TFloat;
const
  ops = '+-*/';
var
  operands: TOperands;
  operations: TOperations;
  opnds_count, optns_count, i, j, len: Byte;
  temp: String;
  _result: TFloat;
begin
  _result := 0;
  opnds_count := 0;
  optns_count := 0;
  len := Length(s);
  i := 1;
  while i <= len do begin
    temp := '';
    if (s[i] = '-') and ((i = 1) or (pos(s[i - 1], ops) > 0)) then begin
       temp := ConCat(temp, '-');
       inc(i);
    end;
    while (i <= len) and not (s[i] in ['+', '-', '*', '/']) do begin
      temp := ConCat(temp, s[i]);
      inc(i);
    end;
    inc(opnds_count);
    operands[opnds_count] := StrToFloat(temp);
    if i <= len then begin
      inc(optns_count);
      operations[optns_count] := s[i];
    end;
    inc(i);
  end;
  SimplifyExpr(operands, operations, opnds_count, optns_count);
  for i := 1 to optns_count do begin
    operands[1] := AtomExpr(operands[1], operands[2], operations[i]);
    for j := 2 to opnds_count - 1 do
     operands[j] := operands[j + 1];
  end;
  SubExpr := operands[1];
end;
function SmartCalc(const s: String): TFloat;
var
  expr, tmp: String;
  break_start, break_end, i: Byte;
begin
  expr := s;
  while Pos('(', expr) > 0 do begin
    i := 1;
    break_start := 0;
    break_end := 0;
    repeat
      while expr[i] <> '(' do
        inc(i);
      break_start := i;
      inc(i);
      while not (expr[i] in ['(', ')']) do
        inc(i);
      if expr[i] = ')' then
        break_end := i;
    until break_end > 0;
    tmp := Copy(expr, break_start + 1, break_end - break_start - 1);
    Delete(expr, break_start, break_end - break_start + 1);
    Insert(FloatTOStr(SubExpr(tmp)), expr, break_start);
    break_end := 0;
  end;
  SmartCalc := SubExpr(expr);
end;
var
  ex1, ex2, ex3, ex4: String;
begin
  clrscr;
  ex1 := '10*(5+2*(1-3))';                      { +10   }
  ex2 := '(-1+(5/2)+3+4+5/2--1*5)';             { +16   }
  ex3 := '-2*(2+3)*4+(2*2+1+-5/2)*2+(2*(6/3))'; { -31   }
  ex4 := '1*10*100+((0*81))+0.5+(((0.5)))';     { +1001 }
  writeln(ex1, ' = ', SmartCalc(ex1):0:2);
  writeln(ex2, ' = ', SmartCalc(ex2):0:2);
  writeln(ex3, ' = ', SmartCalc(ex3):0:2);
  writeln(ex4, ' = ', SmartCalc(ex4):0:2);
  readln;
end.
 
 