VB.NET 中的复数数学解析器和求值器





5.00/5 (15投票s)
简化/求值实数/复数数学表达式
- 下载 ParseComplexTesterDetail - 349.2 KB
- 下载 ParseComplexTester - 303.7 KB
- 下载 ParseComplex_Csharp - 417.9 KB
引言
在很多情况下,可能存在一个包含数学表达式的 string
,例如 "1+2*5
" 或 "(3+i)(3-i)
",并且需要进行数学运算并计算结果。 此外,对于像 "0.5*x+4
" 这样的公式,我们可能需要计算 x
的几个不同值的结果。 在这些情况下,此处提供的复数解析器可能会有所帮助。
这里的类是我所有免费且可下载的 CAS 计算器 http://xrjunque.nom.es 的一小部分(但经过改进)。 其中一个目标是这些类不依赖于其他“外部”类,就像 CAS 计算器中发生的那样。
五个类
Global10
类包含全局值,如小数位数、虚数单位(i
或j
)或CultureInfo
。Msg10
类仅包含一些消息以处理可能的错误。Rational
类在运算中提供了更高的精度。Complex
类执行复数数学运算。parseComplex
类负责将输入字符串分成标记,并相应地调用Complex
或Msg10
类。Complex
类利用Rational
类作为其 Real 和 Imaginary 成员。 “标记化”工作由 Regex 模式完成。
令牌
标记组是
mode <mode>
numbers <num>
operators <op>
logical operators <lop>
functions <fn>
constants <cnt>
variables <var>
any other character <any>
besides end of tokens <end> formed by an escape character Chr(27).
该模式看起来像
(?i)(?<mode>(&dec(?<dec>\d{1,2})|&(rad|deg|grad|[hobdij])))(?-i)
(?<numop>(?<num>((\d{1,3}((\,\d{3})+(?!\d))(\.[0-9]+)?)|
[\d]{1}[\.\dA-Fa-f]*)([eE](\s*)[-+]?[0-9]+)?)|
(?<op>[-+*/\^]))|\(|\)|
(?i)(?<fn>logtwo|logten|acosh|acoth|acsch|asech|asinh|atanh|
floor|round|norm|conj|coth|csch|sech|acos|acot|acsc|asec|asin|atan|cosh|sign|sinh|
sqrt|tanh|abs|cos|cot|csc|exp|log|sec|sin|sqr|tan|ln|re|im)(?![a-zA-Z_]+)|
(?<lop>\<\<|\>\>|nand|mod|and|nor|xor|not|or|%|!)(?![a-zA-Z_]+)|
(?<cnt>e|(?i)pi)(?![a-zA-Z_]+)|
(?<vars>[_a-zA-Z]\w*)+|(?<end>\e)+|
(?<any>[^\s←\,\.])+|(?<any>\,|\.)+
</dec>
数字的模式,取决于 Globalization.CultureInfo
设置,可能会交换点(NumberFormat.NumberDecimalSeparator
)和逗号(NumberFormat.NumberGroupSeparator
)。
模式使得可以输入十六进制、十进制、八进制或二进制基数的数字; 以及设置小数位数和虚数单位。
Using the Code
有两种可能的实例化方式
Dim eP As New ParseComplex
eP.CultureInfo = New Globalization.CultureInfo("fr-FR")
...
Dim eP As New ParseComplex(New Globalization.CultureInfo("es-AR"))
...
默认情况下,CultureInfo
设置为 "en-US
"。
求值是通过调用两个 Evaluate()
方法之一来完成的。
第一种方法
'// argument is a string:
Dim cplx As Complex = eP.Evaluate("(3+5*i)*(3-i*5)")
第一个方法带有变量,设置在 Dictionay(Of String, Complex)
中
eP.vars.Add("x", Complex.one)
eP.vars.Add("y", New Complex(-1, 2))
'// argument is a string:
Dim cplx As Complex = eP.Evaluate("(3+x*i)*(y-i*5)")
解析完 string
后,可以调用重载的第二个方法
'// change "x" value (change any variable value):
eP.vars.Item("x") = New Complex(3)
'// argument is the Dictionary(Of String, Complex):
Dim cplx As Complex = eP.Evaluate(eP.vars)
变量名称以字母或下划线 (_
) 开头,可以包含字母、数字或下划线,并且可以是任意长度。
当然,如果您不需要解析器,您可以直接调用 Complex
类。
默认的数字基数为十进制。 要更改为另一个基数,请写入 &h
(十六进制)、&o
(八进制)或 &b
(二进制)。 附加 &d
将恢复为十进制基数。
以类似的方式,°
、&grad
将接受以度或梯度为单位的角度。 要恢复为默认的弧度,请输入 &rad
。
要将默认虚数单位 i
更改为 j
,请写入 &j
,要返回默认字符,请写入 &i
。
例如,输入 &culture it-IT
会将当前的 CultureInfo
更改为 it-IT
。 因此,输入和输出将以 mented 文化进行。
可能的修饰符的示例如下
Dim cplx As Complex = eP.Evaluate("&culture fr-FR &dec2 &h 0f + &j &d 0,2+0,3*j"
Console.WriteLine(cplx.tostring) ' will show 15,2+j*0,3
输出
您可以调用 Complex.ToString()
或 ToStringComplex( numDecimals As Int32, sImg As String, cultureInfo As Globalization.CultureInfo) As String
cplx.ToStringComplex(4, eP.Imaginary, eP.CultureInfo)
详细版本
如果找到单词 detail
,代码将输出操作步骤。 例如
Dim cP As New ParseComplex
Dim cplx As Complex = cP.Evaluate("detail (2+i*3)*(1+i)")
Console.WriteLine(cP.GetDetail)
' Will output:
' [ (2+i*3)*(1+i) ]
' [2*1 - 3*1 + i*(2*1+3*1) ]
' [-1+i*5]
基本原理
解析方法是递归下降解析: 通过递归下降解析表达式。
求值方法 E
为任何加法或减法调用 T
,但 T
首先为任何乘法或减法调用 F
,并且 F
首先为任何可能的幂运算调用 P。 P
首先调用 v
以获取下一个标记。 如果存在 "(
" 标记,则 v
递归调用 T
。
E --> T {( "+" | "-" ) T}
T --> F {( "*" | "/" ) F}
F --> P ["^" F]
P --> v | "(" E ")" | "-" T
分步演示
此处提出的算法将 T
和 F
包裹在一个方法中。 此外,方法 v
运行逻辑运算符,“%' 和 mod
任何可能的函数,如 cos()
、csc()
等。
在撰写本文时,我发现了一些小问题。 如果您发现任何其他错误,请告诉我。
历史
- 2022 年 3 月 25 日:初始版本