#include <iostream>
#include <string>
#include <stack>
#include <queue>
#include <map>
using namespace std;
struct node{
double num; //操作数
char op; //操作符
bool flag; //true表示操作数, false表示操作符
};
string str;
stack<node> s; //操作符栈
queue<node> q; //后缀表达式序列
map<char, int> op; //操作符优先级栈
void eraseBlank(string &str){
for(string::iterator it=str.end(); it!=str.begin(); it--){
if(*it == ' ') str.erase(it);
}
}
void change(){
double num;
struct node temp;
for(int i=0; i<str.length();){
if(str[i]>='0' && str[i]<='9'){ //如果是数字
temp.flag = true;
temp.num = str[i++] - '0';
while(i<str.length() && str[i] >= '0' && str[i]<='9'){
temp.num = temp.num * 10 + (str[i] - '0');
i++;
}
q.push(temp); //将操作数压入后缀表达式队列
}else{ //如果是操作符
temp.flag = false;
//只要操作符栈不空, 而栈顶元素又比该操作符优先级高
//就把操作符栈的栈顶元素弹出到后缀表达式队列中去
while(!s.empty() && op[str[i]] <= op[s.top().op]){
q.push(s.top());
s.pop();
}
//现在操作符栈的栈顶运算符比待判定的运算符优先级低了
//可以让该运算符入栈了
temp.op = str[i];
s.push(temp);
i++;
}
}
//字符串全部处理完了,如果操作符栈中还有操作符,
//就把它们弹出到后缀表达式队列中去
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
double cal(){
double temp1, temp2;
node cur, temp;
while(!q.empty()){
cur = q.front(); q.pop(); //记录 后缀表达式队列 的 队首元素
if(cur.flag == true) s.push(cur); //如果该队首元素是个符号, 就把这个元素放进操作符栈
else{
temp2 = s.top().num; s.pop(); //弹出第二操作数
temp1 = s.top().num; s.pop(); //弹出第一操作数
temp.flag = true; //临时记录操作数
if(cur.op == '+') temp.num = temp1 + temp2;
else if(cur.op == '-') temp.num = temp1 - temp2;
else if(cur.op == '*') temp.num = temp1 * temp2;
else temp.num = temp1 / temp2;
s.push(temp); //把计算结果压入操作符栈
}
}
return s.top().num;
}
int main(){
op['+'] = op['-'] = 1;
op['*'] = op['/'] = 2;
while(getline(cin, str), str!="0"){
eraseBlank(str); //清除字符串空格
while(!s.empty()) s.pop(); //操作符栈清空
change(); //中缀表达式转后缀表达式
printf("%.2f\n", cal()); //计算后缀表达式
return 0;
}
return 0;
}