View Javadoc
1   package calculator.operations;
2   
3   import java.math.RoundingMode;
4   import java.util.List;
5   
6   import calculator.Expression;
7   import calculator.IllegalConstruction;
8   import calculator.atoms.Complex;
9   import calculator.atoms.IntegerAtom;
10  import calculator.atoms.Rationnal;
11  import calculator.atoms.Real;
12  
13  /**
14   * This class represents the arithmetic division operation "/".
15   * The class extends an abstract superclass Operation.
16   * Other subclasses of Operation represent other arithmetic operations.
17   * 
18   * @see Operation
19   * @see Minus
20   * @see Times
21   * @see Plus
22   */
23  public final class Divides extends Operation {
24  
25  	/**
26  	 * Class constructor specifying a number of Expressions to divide.
27  	 *
28  	 * @param elist The list of Expressions to divide
29  	 * @throws IllegalConstruction If an empty list of expressions if passed as
30  	 *                             parameter
31  	 * @see #Divides(List<Expression>)
32  	 */
33  	public Divides(List<Expression> elist) throws IllegalConstruction {
34  		super(elist);
35  		symbol = "/";
36  		neutral = 1;
37  	}
38  
39  	/**
40  	 * The actual computation of the (binary) arithmetic division of two integers
41  	 * 
42  	 * @param l The first integer
43  	 * @param r The second integer that should divide the first
44  	 * @return The integer that is the result of the division
45  	 */
46  	public int op(int l, int r) {
47  		if (r == 0) {
48  			throw new ArithmeticException("Division by zero");
49  		}
50  		return (l / r);
51  	}
52  
53  	/**
54  	 * The actual computation of the (binary) arithmetic division of two Reals
55  	 * 
56  	 * @param r1 The first Real
57  	 * @param r2 The second Real
58  	 * @return The (new) Real that is the result of the division
59  	 */
60  	public Real op(Real r1, Real r2) {
61  
62  		if (r1.isNan() || r2.isNan()) { // NaN / x = NaN
63  			return Real.nan();
64  		}
65  
66  		if (r2.getValue().doubleValue() == 0) {
67  			if (r1.getValue().doubleValue() == 0)
68  				return Real.nan();
69  			else if (r1.getValue().doubleValue() > 0)
70  				return Real.plusInf();
71  			else if (r1.getValue().doubleValue() < 0)
72  				return Real.minusInf();
73  		}
74  
75  		if ((r1.isPlusInf() && r2.isMinusInf())
76  				|| (r1.isMinusInf() && r2.isPlusInf())
77  				|| (r1.isMinusInf() && r2.isMinusInf())
78  				|| (r1.isPlusInf() && r2.isPlusInf())) { // the case with inf/inf = NaN
79  			return Real.nan();
80  		}
81  
82  		if (r2.isPlusInf() || r2.isMinusInf()) { // x/inf = 0
83  			return new Real(0);
84  		}
85  
86  		if (r1.isPlusInf() || r1.isMinusInf()) { // inf/x = +/- inf
87  			// int whose sign is the resulting sign of the infinity
88  			Double sign = r1.getValue().doubleValue() * r2.getValue().doubleValue();
89  			if (sign > 0)
90  				return Real.plusInf();
91  			else
92  				return Real.minusInf();
93  		}
94  
95  		return new Real(r1.getValue().divide(r2.getValue(), Real.context));
96  	}
97  
98  	/**
99  	 * The actual computation of the (binary) arithmetic division of two
100 	 * Integers
101 	 * 
102 	 * @param i1 The first IntegerAtom
103 	 * @param i2 The second IntegerAtom
104 	 * @return The (new) IntegerAtom that is the result of the division
105 	 */
106 	public IntegerAtom op(IntegerAtom i1, IntegerAtom i2) {
107 		if (i2.getValue() == 0) {
108 			throw new ArithmeticException("Division by zero");
109 		}
110 		return new IntegerAtom(i1.getValue() / i2.getValue());
111 	}
112 
113 	@Override
114 	public Complex op(Complex c1, Complex c2) {
115 		if (c1.isNaN() || c2.isNaN()) {
116 			return Complex.nan();
117 		}
118 
119 		if (c2.getValue().equals(org.apache.commons.numbers.complex.Complex.ZERO)) {
120 			throw new ArithmeticException("Division by zero");
121 		}
122 		org.apache.commons.numbers.complex.Complex result = c1.getValue().divide(c2.getValue());
123 		return new Complex(result);
124 	}
125 
126 	@Override
127 	public Rationnal op(Rationnal q1, Rationnal q2) {
128 		if (q2.getValue().equals(org.apache.commons.numbers.fraction.Fraction.ZERO)) {
129 			throw new ArithmeticException("Division by zero");
130 		}
131 
132 		org.apache.commons.numbers.fraction.Fraction result = q1.getValue().divide(q2.getValue());
133 		return new Rationnal(result);
134 	}
135 }