简体   繁体   English

Java中的数学计算

[英]math calculating in java

I am trying to develop an advanced math expression calculator in Java. 我正在尝试用Java开发高级数学表达式计算器。 My goal is that calculator can determinate expressions like these: 我的目标是计算器可以确定如下表达式:

2 * 6^( log(123) - sin(7)^cos(2) )

lim( (5x^2) / x , x -> 1)
.
.
.

Is there anything (default function, external library) for this in Java or C++? 在Java或C ++中是否有任何东西(默认函数,外部库)?

You could do this... 你可以做...

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Test {
  public static void main(String[] args) throws Exception{
    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String foo = "2 * 6^( log(123) - sin(7)^cos(2) )";
    System.out.println(engine.eval(foo));
    } 
}

In addition if you want to solve the limits, you could always use an API . 另外,如果您想解决这些限制,则可以始终使用API You can send the request with the right syntax for that api, which will give you the result you can parse. 您可以使用该api的正确语法发送请求,这将为您提供可以解析的结果。 This is however harder to program and API's are often not free. 但是,这很难编程,而且API常常不是免费的。 Another option is calculating limits yourself, I'm not aware of APIs for that or standard Java functions. 另一个选择是自己计算限制,我不知道该限制或标准Java函数的API。

If you really want to start from scratch and re-invent the weel I would suggest you build your own eval function. 如果您真的想从头开始并重新发明weel,建议您构建自己的eval函数。 This is a good starting point for that: Java/c++ example . 这是一个很好的起点: Java / c ++ example

This is less of a Java domain question and more of a language parsing problem. 这不是一个Java域问题,而是一个语言解析问题。 The traditional way to approach this is to build a lexer and parser, sometimes in another language, that generates the code in the language you want. 解决此问题的传统方法是构建一个词法分析器和解析器,有时使用另一种语言,以所需的语言生成代码。 This way you separate the parsing concerns from the actual "client" program concerns. 这样,您就可以将解析问题与实际的“客户端”程序问题分开。

This can be easier, in the long run, than trying to write what is going to be a pretty complicated regular expression state machine that will be hard to prove is correct in all cases. 从长远来看,这比尝试编写将要证明在所有情况下都是正确的非常复杂的正则表达式状态机要容易得多。 An infix math parser/processor is interesting enough that having a "little language" version of the rules and definitions makes it a lot easier to prove your program is correct. 固定式数学解析器/处理器非常有趣,以至于拥有“小语言”版本的规则和定义可以使证明程序正确的过程变得容易得多。

In Java you might want to consider ANTLR to generate the parser, though I admit I have never had to use it. 在Java中,您可能要考虑使用ANTLR来生成解析器,尽管我承认我从来没有使用过它。 But my understanding is that ANTLR is familiar enough if you have used Lex & Yacc. 但是我的理解是,如果您使用过Lex&Yacc,那么ANTLR就足够熟悉了。

[UPDATE] [更新]

I don't know if infix is a hard requirement, but parsing complex math using a stack and postfix operations can be much easier to implement if you don't want to generate a parser. 我不知道是否需要infix,但是如果您不想生成解析器,则使用堆栈和后缀操作来解析复杂的数学会更容易实现。 As an added bonus, this allows you to do math like Yoda. 另外,这使您可以像Yoda一样进行数学运算。

If your expressions are not very complex, I think this answer will guide you in the right way: 如果您的表达不是很复杂,我认为此答案将以正确的方式指导您:

Built-in method for evaluating math expressions in Java Java中评估数学表达式的内置方法

If your expressions are rather sophisticated, using limits as in your example, I advice you to take a look at the Dragon Book . 如果您的表达式相当复杂,请使用示例中的限制,建议您看一下《 龙书》 It should be easier to implement an easy expression parser and use some strong math library below. 实现一个简单的表达式解析器并在下面使用一些强大的数学库应该会更容易。

In general, what you need is called a computer algebra system . 通常,您需要的被称为计算机代数系统 I don't know what requirements you have but there are at least 2 general ways to go about it. 我不知道您有什么要求,但是至少有2种一般方法可以解决。

(1) link your program to a library to do the algebraic stuff. (1)将程序链接到库以执行代数运算。 For C++ you can try Yacas and for Python you can try Sympy . 对于C ++,您可以尝试Yacas ,对于Python,您可以尝试Sympy Dunno about Java. 关于Java的Dunno。

(2) write your program separately and talk to a CAS via a socket. (2)单独编写程序,并通过套接字与CAS对话。 In that case the CAS could be anything, eg, Maxima , Sage , etc etc. A socket interface is maybe less work than you might think -- it is certainly much, much less work than reimplementing CAS functions. 在这种情况下,CAS可以是任何东西,例如MaximaSage等。套接字接口的工作量可能比您想象的要少-当然,与重新实现CAS函数相比,工作量要少得多。

My advice, without knowing your requirements, is to write your program in Python and use Sympy. 我的建议(不知道您的要求)是用Python编写程序并使用Sympy。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM