3.2 分数和复数
看其他篇章到目录 选择。
我们讲到数学的计算,难免会遇到分数形式,因为实数的定义就是可以表示为一个分数的形式的数,而加入虚数的复数也是偶尔会遇到的。 Commons Math包中的 fraction和 complex包就分别提供了方法来表示这两种数。
首先来看一个接口 FieldElement<T>,这个接口定义了一个泛型参数,其具体内容定义了 5组方法,分别是加减乘除运算和 getField()方法。具体 Field<T>是什么,这里就不研究了,因为我发现暂时还没有用到它。呵呵。
像这样的无算法和实现的类,具体就是看示例来观察它的运算行为了。
正式开始,先看看 Fraction类,在 fraction子包下的 Fraction类继承了 java中的 Number类,同时实现了 接口 FieldElement<Fraction>。 Fraction的构造方法有 5个,支持给定一个实数来构建分数,也支持给定分子分母的构建方法。具体的见代码吧,因为代码已经非常直观了。
1
/** */
/**
2 *
3 */
4
package
algorithm.math;
5
6
import
org.apache.commons.math.complex.Complex;
7
import
org.apache.commons.math.fraction.Fraction;
8
import
org.apache.commons.math.fraction.FractionConversionException;
9
10
/** */
/**
11 * @author Jia Yu
12 * @date 2010-11-29
13 */
14
public
class
FractionAndComplexTest
{
15
16 /** */ /**
17 * @param args
18 */
19 public static void main(String[] args) {
20 // TODO Auto-generated method stub
21 fraction();
22 System.out.println( " ------------------------------------------------ " );
23 complex();
24 }
25
26 private static void complex() {
27 // TODO Auto-generated method stub
28 Complex z = new Complex( 3.0 , 4.0 );
29 Complex x = new Complex( 5.0 , 7.0 );
30
31 // output directly
32 System.out.println( " complex z = " + z); // ugly
33 System.out.println( " complex z = " + c2s(z)); // organized manually
34 System.out.println( " complex x = " + c2s(x));
35
36 // complex abs
37 System.out.println( " abs of z = " + z.abs());
38 // complex add
39 System.out.println( " z+x = " + c2s(z.add(x)));
40 // complex substrac
41 System.out.println( " z-x = " + c2s(z.subtract(x)));
42 // complex multiply
43 System.out.println( " z*x = " + c2s(z.multiply(x)));
44 // complex sin cos
45 System.out.println( " sin(z) = " + c2s(z.sin()));
46 System.out.println( " cos(z) = " + c2s(z.cos()));
47 // complex conjugate
48 System.out.println( " conjugate of z = " + c2s(z.conjugate()));
49 }
50
51 public static String c2s(Complex c) {
52 if (c.getImaginary() < 0 )
53 return "" + c.getReal() + c.getImaginary() + " i " ;
54 return "" + c.getReal() + " + " + c.getImaginary() + " i " ;
55 }
56
57 private static void fraction() {
58 // TODO Auto-generated method stub
59 Fraction frac1 = new Fraction( 2 , 3 );
60
61 // output directly
62 System.out.println( " frac1 = " + frac1);
63
64 try {
65 Fraction frac2 = new Fraction( 0.5 );
66 System.out.println( " frac2 = " + frac2);
67
68 // fraction doublevalue
69 System.out.println( " frac1's double form is " + frac1.doubleValue());
70 // fraction add
71 System.out.println( " frac1+frac2 = " + frac1.add(frac2));
72 // fraction substract
73 System.out.println( " frac1-frac2 = " + frac1.subtract(frac2));
74 // fraction multiply
75 System.out.println( " frac1*frac2 = " + frac1.multiply(frac2));
76 // fraction divide
77 System.out.println( " frac1/frac2 = " + frac1.divide(frac2));
78 // fraction multiplicative inverse
79 System.out.println( " frac1's inverse is " + frac1.reciprocal());
80
81 // fraction reduction
82 System.out.println( " 5 / 25 = " + Fraction.getReducedFraction( 5 , 25 ));
83 } catch (FractionConversionException e) {
84 // TODO Auto-generated catch block
85 e.printStackTrace();
86 }
87 }
88
89 }
90
看了具体用法,不免要探究一下,分数的这些运算在 Commons Math里是怎么实现的。跟我们直观感觉一样,在 Fraction类内部定义了分子和分母两个 int型的成员变量。我忍不住要把构造方法的源码贴上来:
1
private
Fraction(
double
value,
double
epsilon,
int
maxDenominator,
int
maxIterations)
2
throws
FractionConversionException
3
{
4 long overflow = Integer.MAX_VALUE;
5 double r0 = value;
6 long a0 = ( long )Math.floor(r0);
7 if (a0 > overflow) {
8 throw new FractionConversionException(value, a0, 1l );
9 }
10
11 // check for (almost) integer arguments, which should not go
12 // to iterations.
13 if (Math.abs(a0 - value) < epsilon) {
14 this .numerator = ( int ) a0;
15 this .denominator = 1 ;
16 return ;
17 }
18
19 long p0 = 1 ;
20 long q0 = 0 ;
21 long p1 = a0;
22 long q1 = 1 ;
23
24 long p2 = 0 ;
25 long q2 = 1 ;
26
27 int n = 0 ;
28 boolean stop = false ;
29 do {
30 ++ n;
31 double r1 = 1.0 / (r0 - a0);
32 long a1 = ( long )Math.floor(r1);
33 p2 = (a1 * p1) + p0;
34 q2 = (a1 * q1) + q0;
35 if ((p2 > overflow) || (q2 > overflow)) {
36 throw new FractionConversionException(value, p2, q2);
37 }
38
39 double convergent = ( double )p2 / ( double )q2;
40 if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {
41 p0 = p1;
42 p1 = p2;
43 q0 = q1;
44 q1 = q2;
45 a0 = a1;
46 r0 = r1;
47 } else {
48 stop = true ;
49 }
50 } while ( ! stop);
51
52 if (n >= maxIterations) {
53 throw new FractionConversionException(value, maxIterations);
54 }
55
56 if (q2 < maxDenominator) {
57 this .numerator = ( int ) p2;
58 this .denominator = ( int ) q2;
59 http://www.blogjava.net/Images/OutliningI
分享到:
评论