#include <iostream>
#include<stack>
#include<cstdio>
using namespace std;
char str[220];//保存表达式字符串
int mat[][5] = {//优先级矩阵,0号为表达式首尾的标记运算符,1号为+,2号为-,3号为*,4号为/
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0,
};
stack<int> op;//运算符栈,保存运算符编号
stack<double> in;//数字栈
void getOp(bool &reto, int &retn, int &i){
/**获得下一个元素,如果是运算符,reto为true,编号保存在引用变量retn中;
**如果是数字,值保存在retn中,i表示遍历到的字符串下标
*/
if(i == 0 && op.empty() == true){
//此时遍历字符串第一个字符,且运算符栈为空,人为添加编号为0的标记字符
reto = true;
retn = 0;
return;
}
if(str[i] == 0){
//遍历字符为空字符,表示字符串已经被遍历完
reto = true;
retn = 0;
return;
}
if(str[i] >= '0' && str[i] <= '9'){
//若当前字符为数字,返回为数字
reto = false;
retn = 0;
for(;str[i] != ' ' && str[i] != 0;i++){
retn *= 10;
retn += str[i] - '0';
}
if(str[i] == ' ')
//如果后面是空格,字符串没遍历完,继续向后遍历
i++;
return;
}else{
//当前字符为操作符
reto = true;
if(str[i] == '+')
retn = 1;
else if(str[i] == '-')
retn = 2;
else if(str[i] == '*')
retn = 3;
else if(str[i] == '/')
retn = 4;
i += 2;//跳过字符和后面的空格
return;
}
}
int main()
{
while(gets(str)){
if(str[0] == '0' && str[1] == 0)
break;//输入只有一个0,退出
bool retOp;
int retNum;
int index = 0;
while(!op.empty())
op.pop();//清空字符栈
while(!in.empty())
in.pop();//清空数字栈
while(true){//循环遍历表达式字符串
getOp(retOp,retNum,index);//获取表达式下一个元素
if(retOp == false)//数字
in.push((double)retNum);
else{//运算符
double tmp;
if(op.empty() == true || mat[retNum][op.top()] == 1)
op.push(retNum);//运算符栈为空或当前遍历到的运算符优先级比栈顶运算符大,将该运算符压入运算符堆栈
else{
while(mat[retNum][op.top()] == 0){//当前运算符优先级低
int ret = op.top();
op.pop();
double b = in.top();
in.pop();
double a = in.top();
in.pop();
if(ret == 1)
tmp = a+b;
else if(ret == 2)
tmp = a-b;
else if(ret == 3)
tmp = a*b;
else if(ret == 4)
tmp = a/b;
in.push(tmp);
}
op.push(retNum);
}
}
if(op.size() == 2 && op.top() == 0)
//运算符栈只有两个运算符,且栈顶运算符为0,表示表达式求值结束(这两个运算符分别是开头和结尾的0)
break;
}
printf("%.2f\n",in.top());
}
return 0;
}