3.2 分数和复数
看其他篇章到目录 选择。
我们讲到数学的计算,难免会遇到分数形式,因为实数的定义就是可以表示为一个分数的形式的数,而加入虚数的复数也是偶尔会遇到的。 Commons Math包中的 fraction和 complex包就分别提供了方法来表示这两种数。
首先来看一个接口 FieldElement<T>,这个接口定义了一个泛型参数,其具体内容定义了 5组方法,分别是加减乘除运算和 getField()方法。具体 Field<T>是什么,这里就不研究了,因为我发现暂时还没有用到它。呵呵。
像这样的无算法和实现的类,具体就是看示例来观察它的运算行为了。
正式开始,先看看 Fraction类,在 fraction子包下的 Fraction类继承了 java中的 Number类,同时实现了 接口 FieldElement<Fraction>。 Fraction的构造方法有 5个,支持给定一个实数来构建分数,也支持给定分子分母的构建方法。具体的见代码吧,因为代码已经非常直观了。
/** */
/** 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 Yu12
* @date 2010-11-2913
*/
14

public
class
FractionAndComplexTest
{15

16

/** */ /** 17
* @param args18
*/ 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型的成员变量。我忍不住要把构造方法的源码贴上来:
private
Fraction(
double
value,
double
epsilon,
int
maxDenominator,
int
maxIterations)2
throws
FractionConversionException3

{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 go12
// 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
本文介绍了使用Apache Commons Math库进行分数和复数的数学运算。包括分数的加减乘除及倒数运算,复数的加减乘除、三角函数、共轭等操作,并展示了如何创建分数和复数实例。

被折叠的 条评论
为什么被折叠?



