如何解析&;在JavaScript计算器中处理数学表达式?

如何解析&;在JavaScript计算器中处理数学表达式?,javascript,twitter-bootstrap,Javascript,Twitter Bootstrap,使用javascript计算表达式(如3+1*sin(20)*e^3)的最佳方法是什么 首先,我不想使用内置的数学函数。事实上,我已经为幂、平方根、sin、cos、指数等定义了自己的函数 我要寻找的是一种解析表达式的好方法,这样我就可以将它们传递给我创建的这些函数。我知道JavaScript中有一个eval()函数可用于计算输入表达式,但我不确定这是否适合此上下文 我应该使用eval()?如果是,我如何在这种情况下使用它?如果没有,还有什么更适合解析数学表达式的方法?! 这不是学校的作业,只是一

使用javascript计算表达式(如
3+1*sin(20)*e^3
)的最佳方法是什么

首先,我不想使用内置的数学函数。事实上,我已经为
平方根
sin
cos
指数
等定义了自己的函数

我要寻找的是一种解析表达式的好方法,这样我就可以将它们传递给我创建的这些函数。我知道JavaScript中有一个
eval()
函数可用于计算输入表达式,但我不确定这是否适合此上下文

我应该使用
eval()
?如果是,我如何在这种情况下使用它?如果没有,还有什么更适合解析数学表达式的方法?!
这不是学校的作业,只是一个疑问。

如果你想要更多的数学功能,那么你可能需要使用第三方库,如

要使用此库,请首先将其包含在HTML中:

 <script src='path/to/math.js'></script>
 <script src='path/to/math.js'></script>
使用第三方库 在现实生活中,您可能希望使用类似于库的工具来为您进行计算

要使用此库,请首先将其包含在HTML中:

 <script src='path/to/math.js'></script>
 <script src='path/to/math.js'></script>
也就是说,如果
20
是以弧度表示的值。因为它可能是以度表示的值,所以需要进行以下小调整:

math.eval('3+1*sin(20 deg)*e^3');
因为你明确地说你不想使用内置的数学函数,我怀疑你在做学校作业。请注意,在StackOverflow上提交学校作业是不受欢迎的,因为这被认为是一种作弊形式

但让我们忽略这一点,继续前进,好吗


自己做吧 步骤1:使用内置数学函数进行计算 在实际项目中,您应该始终使用内置数学函数或第三方库(如),这些库在后台使用内置数学函数。这是因为内置的数学函数都是100%可靠和性能优化的

不可能以与内置函数一样可靠和性能优化的方式创建自己的等效内置数学函数,因此没有任何理由不使用内置函数。但是,既然您明确要求它,让我们忽略它,看看如何在没有内置数学函数的情况下进行操作。我认为这也意味着您不想使用或任何其他库

使用JavaScript的内置函数,您可以这样计算表达式:

3+1*Math.sin(20)*Math.pow(Math.E,3)
var dsin = function() {
  var piRatio = Math.PI / 180;
  return function dsin(degrees) {
    return Math.sin(degrees * piRatio);
  };
}();
var pow = function(base, exp) {
  if (exp == 0)
    return 1;
  else
    return base * power(base, exp - 1);
}
var sin = function(x) {
    var t1 = -1,t2 = 3,v1 = x,v2 = v1 + 1,it = 0;
    while (it < 10) {
        v2 = v1 + (t1 * pow(x, t2) / function(n){
        j = 1;
        for(i=1;i<=n;i++)
            j = j*i;
            return j;
        }(t2));
        t1 = -1 * t1;
        t2 += 2;
        v1 = v2;
        it++;
    }
    return v2;
}
3+1*Calc.dsin(20)*Calc.pow(Calc.E,3)
使用的内置功能:

  • 可用于计算
    x的
    sin
  • 可用于计算
    xⁿ
  • 是表示
    e
在这里,同样重要的是,只有当
20
是弧度值时,才说明这是正确的。由于
20
可能是以度为单位的值,因此您可能需要定义自己的基于度的sin函数,如下所示:

3+1*Math.sin(20)*Math.pow(Math.E,3)
var dsin = function() {
  var piRatio = Math.PI / 180;
  return function dsin(degrees) {
    return Math.sin(degrees * piRatio);
  };
}();
var pow = function(base, exp) {
  if (exp == 0)
    return 1;
  else
    return base * power(base, exp - 1);
}
var sin = function(x) {
    var t1 = -1,t2 = 3,v1 = x,v2 = v1 + 1,it = 0;
    while (it < 10) {
        v2 = v1 + (t1 * pow(x, t2) / function(n){
        j = 1;
        for(i=1;i<=n;i++)
            j = j*i;
            return j;
        }(t2));
        t1 = -1 * t1;
        t2 += 2;
        v1 = v2;
        it++;
    }
    return v2;
}
3+1*Calc.dsin(20)*Calc.pow(Calc.E,3)
现在,将
Math.sin
替换为
dsin

3+1*dsin(20)*Math.pow(Math.E,3)
在任何实际应用程序中,最好的方法是计算
3+1*sin(20)*e^3

第2步:用自己的函数重演内置的数学函数 现在,当你真的,真的,真的想离开内置函数时,下一步就是用一个自己编写的等价函数替换每个内置函数。通常,有多条数学路径通向同一个目标

例如,您可以像这样递归地编写
pow
函数:

3+1*Math.sin(20)*Math.pow(Math.E,3)
var dsin = function() {
  var piRatio = Math.PI / 180;
  return function dsin(degrees) {
    return Math.sin(degrees * piRatio);
  };
}();
var pow = function(base, exp) {
  if (exp == 0)
    return 1;
  else
    return base * power(base, exp - 1);
}
var sin = function(x) {
    var t1 = -1,t2 = 3,v1 = x,v2 = v1 + 1,it = 0;
    while (it < 10) {
        v2 = v1 + (t1 * pow(x, t2) / function(n){
        j = 1;
        for(i=1;i<=n;i++)
            j = j*i;
            return j;
        }(t2));
        t1 = -1 * t1;
        t2 += 2;
        v1 = v2;
        it++;
    }
    return v2;
}
3+1*Calc.dsin(20)*Calc.pow(Calc.E,3)
迭代实现:

var pow = function(base, exp) {
  var result = 1;
  while(exp--) {
    result *= base;
  }
  return result;
}
那现在怎么办,你问?!你会问,如果不依赖
Math.sin
,如何实现
dsin

嗯。。。一点研究告诉你,你可以使用公式
sin(x)=x-x^3/3!+计算
sin
x^5/5!-x^7/7!+x^9/9!-

在JavaScript中,这类似于:

3+1*Math.sin(20)*Math.pow(Math.E,3)
var dsin = function() {
  var piRatio = Math.PI / 180;
  return function dsin(degrees) {
    return Math.sin(degrees * piRatio);
  };
}();
var pow = function(base, exp) {
  if (exp == 0)
    return 1;
  else
    return base * power(base, exp - 1);
}
var sin = function(x) {
    var t1 = -1,t2 = 3,v1 = x,v2 = v1 + 1,it = 0;
    while (it < 10) {
        v2 = v1 + (t1 * pow(x, t2) / function(n){
        j = 1;
        for(i=1;i<=n;i++)
            j = j*i;
            return j;
        }(t2));
        t1 = -1 * t1;
        t2 += 2;
        v1 = v2;
        it++;
    }
    return v2;
}
3+1*Calc.dsin(20)*Calc.pow(Calc.E,3)
步骤3:解析 如果您确实希望应用程序直接读取类似于
3+1*sin(20)*e^3
的表达式,则不应使用
eval()
。相反,您应该编写自己的解析器

正确的方法是首先编写一个标记器,将表达式转换为语法树。然后,将语法树传递给解释器,解释器通过运行在步骤1中创建的计算函数来处理语法树


要深入了解如何构建语法树和解释器,您可以查看。

请。答案是“仅仅是一个指向外部站点的链接”。我想知道如何解决这个问题。使用一个库。这是一个图书馆的链接。这里是一个指向一些文档的链接“仍然”仅仅是一个指向外部站点的链接“
DOM
元素的
id
应该是唯一的;
keys
设置为
id
多个
input
元素在
html
中的
编辑:我不想使用内置函数。我应该如何计算表达式?”
Math.pow
似乎用于
js
x=Math.pow(x,y);
?可能重复“我不想使用内置函数”。我应该如何计算表达式?“-听起来您真的在寻找如何手动实现sin查找的描述。这更像是一个数学问题,而不是一个编程问题。你的问题太宽泛了,请更具体一点,在评估你的问题时,你的问题到底是什么?请只发布相关代码并描述具体问题。我问的是如何解决一个表达式而不是正弦函数的实现。请参阅OP中的“不想使用内置数学函数”。@guest271314:我只是注意到,在OP编辑了他的问题之后。我正在编辑我的答案。注意“不想使用内置的数学函数”也不是