1 21 22 package org.armedbear.lisp; 23 24 public final class Complex extends LispObject 25 { 26 private final LispObject realpart; 27 private final LispObject imagpart; 28 29 private Complex(LispObject realpart, LispObject imagpart) 30 { 31 this.realpart = realpart; 32 this.imagpart = imagpart; 33 } 34 35 public static LispObject getInstance(LispObject realpart, 36 LispObject imagpart) 37 throws ConditionThrowable 38 { 39 if (!realpart.realp()) 40 return signal(new TypeError(realpart, Symbol.REAL)); 41 if (!imagpart.realp()) 42 return signal(new TypeError(imagpart, Symbol.REAL)); 43 if (realpart instanceof LispFloat) 44 imagpart = LispFloat.coerceToFloat(imagpart); 45 else if (imagpart instanceof LispFloat) 46 realpart = LispFloat.coerceToFloat(realpart); 47 if (imagpart instanceof Fixnum) { 48 if (((Fixnum)imagpart).getValue() == 0) 49 return realpart; 50 } 51 return new Complex(realpart, imagpart); 52 } 53 54 public LispObject getRealPart() 55 { 56 return realpart; 57 } 58 59 public LispObject getImaginaryPart() 60 { 61 return imagpart; 62 } 63 64 public LispObject typeOf() 65 { 66 return Symbol.COMPLEX; 67 } 68 69 public LispClass classOf() 70 { 71 return BuiltInClass.COMPLEX; 72 } 73 74 public LispObject typep(LispObject type) throws ConditionThrowable 75 { 76 if (type == Symbol.COMPLEX) 77 return T; 78 if (type == Symbol.NUMBER) 79 return T; 80 if (type == BuiltInClass.COMPLEX) 81 return T; 82 if (type == BuiltInClass.NUMBER) 83 return T; 84 return super.typep(type); 85 } 86 87 public LispObject NUMBERP() 88 { 89 return T; 90 } 91 92 public boolean numberp() 93 { 94 return true; 95 } 96 97 public boolean eql(LispObject obj) 98 { 99 if (this == obj) 100 return true; 101 if (obj instanceof Complex) { 102 Complex c = (Complex) obj; 103 return realpart.eql(c.realpart) && imagpart.eql(c.imagpart); 104 } 105 return false; 106 } 107 108 public boolean equal(LispObject obj) 109 { 110 return eql(obj); 111 } 112 113 public boolean equalp(LispObject obj) throws ConditionThrowable 114 { 115 return isEqualTo(obj); 116 } 117 118 public final LispObject incr() throws ConditionThrowable 119 { 120 return new Complex(realpart.add(Fixnum.ONE), imagpart); 121 } 122 123 public final LispObject decr() throws ConditionThrowable 124 { 125 return new Complex(realpart.subtract(Fixnum.ONE), imagpart); 126 } 127 128 public LispObject add(LispObject obj) throws ConditionThrowable 129 { 130 if (obj instanceof Complex) { 131 Complex c = (Complex) obj; 132 return getInstance(realpart.add(c.realpart), imagpart.add(c.imagpart)); 133 } 134 return getInstance(realpart.add(obj), imagpart); 135 } 136 137 public LispObject subtract(LispObject obj) throws ConditionThrowable 138 { 139 if (obj instanceof Complex) { 140 Complex c = (Complex) obj; 141 return getInstance(realpart.subtract(c.realpart), imagpart.subtract(c.imagpart)); 142 } 143 return getInstance(realpart.subtract(obj), imagpart); 144 } 145 146 public LispObject multiplyBy(LispObject obj) throws ConditionThrowable 147 { 148 if (obj instanceof Complex) { 149 LispObject a = realpart; 150 LispObject b = imagpart; 151 LispObject c = ((Complex)obj).getRealPart(); 152 LispObject d = ((Complex)obj).getImaginaryPart(); 153 LispObject ac = a.multiplyBy(c); 157 LispObject bd = b.multiplyBy(d); 158 return Complex.getInstance(ac.subtract(bd), 159 a.add(b).multiplyBy(c.add(d)).subtract(ac).subtract(bd)); 160 } 161 return Complex.getInstance(realpart.multiplyBy(obj), 162 imagpart.multiplyBy(obj)); 163 } 164 165 public LispObject divideBy(LispObject obj) throws ConditionThrowable 166 { 167 if (obj instanceof Complex) { 168 LispObject a = realpart; 169 LispObject b = imagpart; 170 LispObject c = ((Complex)obj).getRealPart(); 171 LispObject d = ((Complex)obj).getImaginaryPart(); 172 LispObject ac = a.multiplyBy(c); 173 LispObject bd = b.multiplyBy(d); 174 LispObject bc = b.multiplyBy(c); 175 LispObject ad = a.multiplyBy(d); 176 LispObject denominator = c.multiplyBy(c).add(d.multiplyBy(d)); 177 return Complex.getInstance(ac.add(bd).divideBy(denominator), 178 bc.subtract(ad).divideBy(denominator)); 179 } 180 return Complex.getInstance(realpart.divideBy(obj), 181 imagpart.divideBy(obj)); 182 } 183 184 public boolean isEqualTo(LispObject obj) throws ConditionThrowable 185 { 186 if (obj instanceof Complex) { 187 Complex c = (Complex) obj; 188 return (realpart.isEqualTo(c.realpart) && 189 imagpart.isEqualTo(c.imagpart)); 190 } 191 if (obj.numberp()) { 192 if (imagpart instanceof LispFloat) { 194 if (((LispFloat)imagpart).getValue() == 0) { 195 if (obj instanceof Fixnum) 196 return ((Fixnum)obj).getValue() == ((LispFloat)realpart).getValue(); 197 if (obj instanceof LispFloat) 198 return ((LispFloat)obj).getValue() == ((LispFloat)realpart).getValue(); 199 } 200 } 201 return false; 202 } 203 signal(new TypeError(obj, "number")); 204 return false; 206 } 207 208 public boolean isNotEqualTo(LispObject obj) throws ConditionThrowable 209 { 210 return !isEqualTo(obj); 211 } 212 213 public LispObject ABS() throws ConditionThrowable 214 { 215 double real = LispFloat.coerceToFloat(realpart).getValue(); 216 double imag = LispFloat.coerceToFloat(imagpart).getValue(); 217 return new LispFloat(Math.sqrt(real * real + imag * imag)); 218 } 219 220 public boolean zerop() throws ConditionThrowable 221 { 222 return realpart.zerop() && imagpart.zerop(); 223 } 224 225 public LispObject COMPLEXP() 226 { 227 return T; 228 } 229 230 public int sxhash() throws ConditionThrowable 231 { 232 return (mix(realpart.sxhash(), imagpart.sxhash()) & 0x7fffffff); 233 } 234 235 public int psxhash() throws ConditionThrowable 236 { 237 return (mix(realpart.psxhash(), imagpart.psxhash()) & 0x7fffffff); 238 } 239 240 public String writeToString() throws ConditionThrowable 241 { 242 StringBuffer sb = new StringBuffer ("#C("); 243 sb.append(realpart.writeToString()); 244 sb.append(' '); 245 sb.append(imagpart.writeToString()); 246 sb.append(')'); 247 return sb.toString(); 248 } 249 } 250 | Popular Tags |