Android 应用程序分析之Calculator ----核心计算部分的理解和高精度运算

 

对于Android的计算器很多人觉得很强大,因为他不光实现了一般计算机所实现的基本计算。更实现了表达式如”(6+3)*3/5-34+(3-5)”的计算,这使得许多小学生做加减乘数算术作业时,可以直接使用该计算器一次得出结果,大大减少了作业的时间开销。

1.Android Calculator的核心计算部分

因为计算结果,是通过界面上按=号键进行的。对Event的处理,放在EventListener.java之中,在OnClick()点击事件中,我们找到计算表达式的代码入口。

EventListener.java:

Android 应用程序分析之Calculator ----核心计算部分的理解和高精度运算_第1张图片

Logic.java:

Android 应用程序分析之Calculator ----核心计算部分的理解和高精度运算_第2张图片

clip_image006Android 应用程序分析之Calculator ----核心计算部分的理解和高精度运算_第3张图片

这个arity的jar包放在Caculator目录下,版本号1.3.3版:clip_image010

Arity的google code地址:

http://code.google.com/p/arity/

2.Android Calculator实现高精度表达式计算

由于Caculator目前并不支持高精度表达式运算,对于大数(包括整数和小数)会做近似处理,要是Android若对高精度的数运算支持,那就更完美了。基于此点出发,为Caculator添加高精度表达式运算的支持,一个方法是下载Arity的源码包进行修改,添加重写运算对高精度的支持。但由于对Arity的源码不太了解,并未找到其对表达式运算的部分,Arity疑似把该部分,交给了一个简单虚拟机进行处理。

另一个方法是,不使用Arity,自己去实现表达式运算部分。考虑到该部分实现不算太复杂,决定自己来实现。

高精度运算主要就是实现两个数(这两个数用数组表示,在Android或着说在Java中也可以用字符串表示,因为其字符串长度可以是由内存决定的,就是说,可以非常的长)的人工加减乘除运算。实现时必须考虑到对“负数”、“括号”、“浮点数”的支持和运算。

在我实现了加、减、乘的运算后(我实现的高精度运算见Operation类),无意发现Java竟然提供了对高精度支持的类BigDecimal(不得不说这是Java的优势,更高高度的大范围封装,减轻了不少程序员的负担。换了C和C++,大多情况还是得老老实实自己写)。那就更省事了。我们主要任务,转移到实现表达式的运算部分。

表达式运算有一个重要的部分,就是判断表达式的正确与否。这里牵涉到较为复杂的此法语法分析。由于不是做编译器。简单的,我们用异常处理就可以解决。

表达式计算的过程主要是依赖一个堆栈数据结构。通过运算符和操作符的进出栈完成对表达式的运算。在这里,我没有直接用堆栈的数据结构去实现。而是使用了递归,把出入栈的过程,交给了计算机去管理。这样的好处就是使得代码写起来更容易,同时,读起来,也更好读。当然,使用递归得牺牲一点时间和空间,但这对于当前计算机运算能力来说,更好的代码可读性和重用性明显也显得十分重要。

用表达式(1+2)*(3-4)举例说明表达式计算主要步骤:

(1+2)*(3-4)进入递归函数:

步骤

表达式

1、去除表达式中多余的括号。

(1+2)*(3-4)

2、找出优先级最低的运算符。把运算符左右部分分别递归运算。然后把运算的结果根据运算符进行操作。

这里最低优先级的符号式*号,因为+号和减在括号内,优先级更高。

3、若递归后的字表达式不含符号,则为但一值。直接返回该值。否则,把左右两边分别递归运算求值。

含符号,分别把(1+2)和(3-4)作为表达式作为新的表达式用同样的方法分别求值(最后左表达式分解为1和2,右表达式又分解为3和4)。从整体层次上讲,就是一颗二叉树的展开。

4、把左右表达式的值根据最低优先级符号进行操作。

左表达式(1+2)递归运算结果为 3

右表达式(3+4)递归运算结果为 -1

所以(1+2)*(3-4) = -3

Android 应用程序分析之Calculator ----核心计算部分的理解和高精度运算_第4张图片

具体表达式运算实现的详细注释和代码,见Expression.java类。

3.Caculator源码的修改与Expression类的不足

3.1代码修改

把Expression.java类加入到Calculator中,把Logic.java:中的

clip_image013

改成使用Expression进行计算,当然,计算前得把Android的特殊+-×÷(Java中使用+/u2212/u00d7/u00f7表示,可以使用Java中的native2ascii进行转换),换成Expression类中的+-*/。

3.2不足

高精度的运算中,仅仅实现了加减乘除和括号的运算。并未实现其他数学符号。比如乘方、log()、ln()、和三角函数的实现,除乘方外,其他函数的实现牵涉到过多的数学知识。并未实现高精度的运算。因此,修改后的计算器,因为未完善的原因,并不支持加减乘除和括号外的运算。若开发上游需要,可以把该计算器作为一个单独的应用程序,供选择使用。有兴趣的朋友,有兴趣可以把剩下其他的数学函数都实现了。(乘方还是很容易实现的吧^-^)

全文完。

附件:

http://download.csdn.net/source/2807815

 

你可能感兴趣的:(java,数据结构,android,虚拟机,编译器,作业)