MATLAB (v7.8.0)
Number of characters: 239
Obfuscated function:
function [v,s]=m(s),r=1;while s,s=regexp(s,'( ?)(?(1)-?)[\.\d]+|\S','match');c=s{end};s=[s{1:end-1}];if any(c>47),v=str2num(c);elseif c>41,[l,s]=m(s);v=[l/v l*v l+v l-v];v=v(c=='/*+-');if r,break;end;r=1;elseif c<41,break;end;r=r&c~=41;end
Clear(er) function:
function [value,str] = math(str)
returnNow = 1;
while str,
str = regexp(str,'( ?)(?(1)-?)[\.\d]+|\S','match');
current = str{end};
str = [str{1:end-1}];
if any(current > 47),
value = str2num(current);
elseif current > 41,
[leftValue,str] = math(str);
value = [leftValue/value leftValue*value ...
leftValue+value leftValue-value];
value = value(current == '/*+-');
if returnNow,
break;
end;
returnNow = 1;
elseif current < 41,
break;
end;
returnNow = returnNow & (c ~= 41);
end
Test:
>> [math('1 + 3 / -8'); ...
math('2*3*4*5+99'); ...
math('4 * (9 - 4) / (2 * 6 - 2) + 8'); ...
math('1 + ((123 * 3 - 69) / 100)'); ...
math('2.45/8.5*9.27+(5*0.0023)')]
ans =
-0.5000
219.0000
10.0000
4.0000
2.6834
Synopsis: A mixture of regular expressions and recursion. Pretty much the best I have been able to do so far, without cheating and using EVAL.