用javascript计算像3+1*sin(20)*e^3
这样的表达式的最佳方法是什么?
首先,我不想使用内置的数学函数。实际上,我已经为power
、square root
、sin
、cos
、exponential
等定义了自己的函数。
我正在寻找的是一种解析表达式的好方法,这样我就可以将它们传递给我创建的这些函数。我知道JavaScript中有一个eval()
函数可以用来计算输入表达式,但我不确定它是否适合这个上下文。
我应该使用eval()
吗?如果是,在这种情况下如何使用它?如果不是,那么解析数学表达式的更合适的方法是什么?这不是学校布置的作业,只是个疑问。
3条答案
按热度按时间rqqzpn5f1#
使用第三方库
在真实的生活中,您可能希望使用math.js这样的库来为您进行计算。
要使用此库,请首先将其包含在HTML中:
然后,你可以使用
math.eval
方法来计算你的表达式:也就是说,如果
20
是以弧度表示的值。由于它可能是以度表示的值,因此需要进行以下小调整:因为你明确地说你不想使用内置的数学函数,我怀疑你正在做一个学校作业。请注意,在StackOverflow上提交学校作业是不受欢迎的,因为它被认为是一种作弊形式。
但我们别管这事继续吧?!
独自一人
第一步:内置数学函数计算
在真实的生活中的项目中,你应该始终使用内置的数学函数或第三方库(如math.js),这些库在后台使用内置的数学函数。这是因为内置的数学函数都是100%可靠和性能优化。
不可能创建自己的等效内置数学函数,其可靠性和性能优化程度与内置函数相同,因此永远没有充分的理由不使用内置函数。但是既然你明确要求了,让我们忽略它,看看如何在没有内置数学函数的情况下做事情。我假设这也暗示了您不想使用math.js或任何其他库。
使用JavaScript的内置函数,你可以像这样计算你的表达式:
使用的内置函数:
Math.sin(x)
可用于计算x
的sin
Math.pow(x, n)
可用于计算xⁿ
Math.E()
是表示e
的常数这里,同样重要的是,只有当
20
是以弧度为单位的值时,这才为真。由于20
可能是一个度数值,你可能想定义自己的基于度数的sin函数,如下所示:现在,将
Math.sin
替换为dsin
:在任何真实的世界的应用程序中,this将是最好的计算
3+1*sin(20)*e^3
!第二步:将内置的数学函数替换为自己的函数
现在,当你真的,真的,真的看起来不想使用内置函数时,下一步就是用一个自己编写的等效函数替换每个内置函数。通常情况下,有多个数学路径朝向同一个目标。
例如,你可以像这样递归地编写
pow
函数:迭代实现:
现在怎么办,你问。!您会问,如何在不依赖
Math.sin
的情况下实现dsin
?!嗯……一点点研究告诉你,你可以计算
sin
,使用公式sin(x) = x - x^3 / 3! + x^5 / 5! - x^7 / 7! + x^9 / 9! - ...
在JavaScript中,这将是这样的:
您可能注意到我将阶乘计算放在lambda函数中。一个更优雅的解决方案是将lambda函数放在一个单独的函数中,因为您可能在其他地方需要它。
现在,你只需要把所有的碎片拼在一起,然后把它们 Package 在一个漂亮的对象中:
你可以像这样使用这些对象的方法:
第三步:解析
如果你真的希望你的应用程序直接读取像
3+1*sin(20)*e^3
这样的表达式,你不应该使用eval()
。相反,您应该编写自己的解析器。正确的方法是首先编写一个标记器,将表达式转换为语法树。然后,将语法树传递给解释器,该解释器通过运行在步骤1中创建的计算函数来处理语法树。
要深入了解如何构建语法树和解释器,您可以查看this tutorial。
5jdjgkvh2#
我写了一个解析器,它可以满足你的需要。它被称为SwanJS,它不使用
eval
或new Function
。安装:
用途:
如果您不喜欢
**
作为幂运算符,您可以更改它,但这并没有很好的文档记录。看看/lib/interpreter.js
,看看如何定义一个新的语法,或者问我,如果你喜欢。shstlldc3#
如果你想要更多的数学功能,除了standard JavaScript math library,那么你可能想使用第三方库,如math.js。
要使用此库,请首先将其包含在HTML中:
然后,你可以使用
math.eval
方法来计算你的表达式: