|
80 | 80 | import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
|
81 | 81 | import com.oracle.graal.python.runtime.exception.PythonErrorType;
|
82 | 82 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
| 83 | +import com.oracle.truffle.api.dsl.Cached; |
83 | 84 | import com.oracle.truffle.api.dsl.Fallback;
|
84 | 85 | import com.oracle.truffle.api.dsl.GenerateNodeFactory;
|
85 | 86 | import com.oracle.truffle.api.dsl.NodeFactory;
|
86 | 87 | import com.oracle.truffle.api.dsl.Specialization;
|
87 | 88 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
| 89 | +import com.oracle.truffle.api.profiles.ConditionProfile; |
88 | 90 |
|
89 | 91 | @CoreFunctions(extendClasses = PythonBuiltinClassType.PComplex)
|
90 | 92 | public class ComplexBuiltins extends PythonBuiltins {
|
@@ -289,11 +291,31 @@ PComplex doComplexPInt(PComplex right, PInt left) {
|
289 | 291 | }
|
290 | 292 |
|
291 | 293 | @Specialization
|
292 |
| - PComplex doComplex(PComplex left, PComplex right) { |
293 |
| - double opNormSq = right.getReal() * right.getReal() + right.getImag() * right.getImag(); |
294 |
| - double realPart = left.getReal() * right.getReal() - left.getImag() * -right.getImag(); |
295 |
| - double imagPart = left.getReal() * -right.getImag() + left.getImag() * right.getReal(); |
296 |
| - return factory().createComplex(realPart / opNormSq, imagPart / opNormSq); |
| 294 | + PComplex doComplex(PComplex left, PComplex right, |
| 295 | + @Cached("createBinaryProfile()") ConditionProfile topConditionProfile, |
| 296 | + @Cached("createBinaryProfile()") ConditionProfile zeroDivisionProfile) { |
| 297 | + double absRightReal = right.getReal() < 0 ? -right.getReal() : right.getReal(); |
| 298 | + double absRightImag = right.getImag() < 0 ? -right.getImag() : right.getImag(); |
| 299 | + double real; |
| 300 | + double imag; |
| 301 | + if (topConditionProfile.profile(absRightReal >= absRightImag)) { |
| 302 | + /* divide tops and bottom by right.real */ |
| 303 | + if (zeroDivisionProfile.profile(absRightReal == 0.0)) { |
| 304 | + throw raise(PythonErrorType.ZeroDivisionError, "complex division by zero"); |
| 305 | + } else { |
| 306 | + double ratio = right.getImag() / right.getReal(); |
| 307 | + double denom = right.getReal() + right.getImag() * ratio; |
| 308 | + real = (left.getReal() + left.getImag() * ratio) / denom; |
| 309 | + imag = (left.getImag() - left.getReal() * ratio) / denom; |
| 310 | + } |
| 311 | + } else { |
| 312 | + /* divide tops and bottom by right.imag */ |
| 313 | + double ratio = right.getReal() / right.getImag(); |
| 314 | + double denom = right.getReal() * ratio + right.getImag(); |
| 315 | + real = (left.getReal() * ratio + left.getImag()) / denom; |
| 316 | + imag = (left.getImag() * ratio - left.getReal()) / denom; |
| 317 | + } |
| 318 | + return factory().createComplex(real, imag); |
297 | 319 | }
|
298 | 320 |
|
299 | 321 | @SuppressWarnings("unused")
|
@@ -533,13 +555,19 @@ PNotImplemented doGeneric(Object left, Object right) {
|
533 | 555 | }
|
534 | 556 |
|
535 | 557 | @GenerateNodeFactory
|
| 558 | + @TypeSystemReference(PythonArithmeticTypes.class) |
536 | 559 | @Builtin(name = __NE__, minNumOfPositionalArgs = 2)
|
537 | 560 | abstract static class NeNode extends PythonBinaryBuiltinNode {
|
538 | 561 | @Specialization
|
539 | 562 | boolean doComplex(PComplex left, PComplex right) {
|
540 | 563 | return left.notEqual(right);
|
541 | 564 | }
|
542 | 565 |
|
| 566 | + @Specialization |
| 567 | + boolean doComplex(PComplex left, long right) { |
| 568 | + return left.getImag() != 0 || left.getReal() != right; |
| 569 | + } |
| 570 | + |
543 | 571 | @SuppressWarnings("unused")
|
544 | 572 | @Fallback
|
545 | 573 | PNotImplemented doGeneric(Object left, Object right) {
|
@@ -632,7 +660,7 @@ int hash(PComplex self) {
|
632 | 660 | return realHash + PComplex.IMAG_MULTIPLIER * imagHash;
|
633 | 661 | }
|
634 | 662 | }
|
635 |
| - |
| 663 | + |
636 | 664 | @GenerateNodeFactory
|
637 | 665 | @Builtin(name = "conjugate", minNumOfPositionalArgs = 1)
|
638 | 666 | abstract static class ConjugateNode extends PythonUnaryBuiltinNode {
|
|
0 commit comments