我如何评估小数和&科学符号中的浮点数 - 例如{} 1.23e4。在postfix?

时间:2017-10-18 13:14:02

标签: c stack postfix

我已经编写了我的代码来评估从postfix到结果。但是,当后缀为小数时,我仍然坚持如何做到这一点。科学符号中的浮点数 - 例如{} 1.23e4。任何具体的建议将受到高度赞赏。谢谢。

#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

#define SIZE 50 /* Size of Stack */

double s[SIZE];
int top=-1; /* Global declarations */
int flag=0;
double pop()
{                      /* Function for POP operation */
  return(s[top--]);
}
double push(double elem)
{ /* Function for PUSH operation */
  if(flag==1){
    int num;
    num=pop();
    s[++top]=elem+10*num;
  }
  else if(flag==0){
    s[++top]=elem;
    flag=1;
  }
}


void main()
{                         /* Main Program */
  char pofx[50],ch;
  int i=0;

  double op1,op2;
  printf("Enter the Postfix Expression:");
  fgets(pofx,100,stdin);
  while( (ch=pofx[i++]) != '\n')
  {
    if(isdigit(ch)) push(ch-'0'); /* Push the operand */
    else if(ch==' ')
      flag=0;
    else
    {        /* Operator,pop two  operands */
      flag=0;
      op2=pop();
      op1=pop();
      switch(ch)
      {
        case '+':push(op1+op2);break;
        case '-':push(op1-op2);break;
        case '*':push(op1*op2);break;
        case '/':push(op1/op2);break;
        case '^':push(pow(op1,op2));break;
        default:
                 printf("Input invalid ... give proper input\n");
                 return 0;
      }
    }
  }
  printf("Result: %lf\n",s[top]);
}

2 个答案:

答案 0 :(得分:1)

  

如何评估小数和&amp;科学电子符号中的浮点数...(?)

要将字符串转换为FP值,请使用strtod() @M Oehm

然而,代码还存在其他问题,即运算符符号'-''+'也可能会开始有效的值标记,如-123.45

// insufficient test to determine if the next part of the string is a number or operator.
if(isdigit(ch)) 
  push(ch-'0');

使用strtod()将文字转换为double ,然后确定字符串的下一部分是否为double

替代代码:

  const char *st = pofx;
  while (*st) {
    char *end; //location to store end of FP parsing
    double value = strtod(st, &end);
    if (end > st) {
      push(value);
      st = end; 
    } else if (isspace((unsigned char) *st)) {
      st++;
    } else {
      switch (*st) {
        case '+':push(pop() + pop());break; // pop order irrelevant
        case '-':{ double t = pop(); push(pop() - t);break; } // pop order relevant
        case '*':push(pop() * pop());break;
        ...
        default: {
          printf("Input invalid operator: character code %d\n", *st);
          return 0;
        } 
      }  // end switch
      st++;
    }
  }

重写push()

void push(double elem) {
  if (top + 1 >= SIZE) {
    printf("Stack overflow\n");
    return;
  }
  s[++top] = elem;
}

fgets()

的错误参数
char pofx[50];
// fgets(pofx,100,stdin); // 100??
fgets(pofx, sizeof pofx, stdin); // better

答案 1 :(得分:0)

来自strtod的{​​{1}}函数会为您解析<stdlib.h>。它需要解析字符串和指向字符串的指针,该字符串将以第一个未解析的字符开头。 (对于长整数,double有类似的功能。)

以下是一个如何在您的情况下工作的示例。 (代码只打印出令牌,不进行任何计算。)

strtol

请注意,这仍然非常粗糙。像#include <stdlib.h> #include <stdio.h> #include <ctype.h> int is_number(const char *p) { if (*p == '-' || *p == '+') p++; if (*p == '.') p++; return isdigit((unsigned char) *p); } int main(void) { const char *line = " .1 20.1* 1.0e-3+2e+7 * -1.0*"; const char *p = line; while (isspace((unsigned char) *p)) p++; while (*p) { if (is_number(p, after_op)) { char *end; double x = strtod(p, &end); if (p == end) { puts("Illegal number"); p++; } else { printf("Number %g\n", x); p = end; } } else { int c = *p++; switch (c) { case '+': puts("Operator add"); break; case '-': puts("Operator sub"); break; case '*': puts("Operator mult"); break; case '/': puts("Operator div"); break; case '^': puts("Operator pow"); break; default: printf("Illegal char '%c'\n", c); } } while (isspace((unsigned char) *p)) p++; } return 0; } 这样的字符串将被解析为数字20,未知字符20x21和数字21.虽然此代码在检测和报告错误方面很糟糕(实际上应该这样做,但它仍然是练习,yadda,yadda),它适用于有效输入。

[编辑:我已经合并了chux的建议,并且使代码兼容读取带有显式符号的数字,但这意味着二元运算符x并且-不能立即跟随数字。选择你的毒药。我还允许删除版本,从而省略一个前导零,例如+,一种我不太喜欢的格式。]