@@ -16,6 +16,8 @@ package grumpy
1616
1717import (
1818 "math"
19+ "math/big"
20+ "math/cmplx"
1921 "testing"
2022)
2123
@@ -42,6 +44,56 @@ func TestComplexEq(t *testing.T) {
4244 }
4345}
4446
47+ func TestComplexBinaryOps (t * testing.T ) {
48+ cases := []struct {
49+ fun func (f * Frame , v , w * Object ) (* Object , * BaseException )
50+ v , w * Object
51+ want * Object
52+ wantExc * BaseException
53+ }{
54+ {Add , NewComplex (1 + 3i ).ToObject (), NewInt (1 ).ToObject (), NewComplex (2 + 3i ).ToObject (), nil },
55+ {Add , NewComplex (1 + 3i ).ToObject (), NewFloat (- 1 ).ToObject (), NewComplex (3i ).ToObject (), nil },
56+ {Add , NewComplex (1 + 3i ).ToObject (), NewInt (1 ).ToObject (), NewComplex (2 + 3i ).ToObject (), nil },
57+ {Add , NewComplex (1 + 3i ).ToObject (), NewComplex (- 1 - 3i ).ToObject (), NewComplex (0i ).ToObject (), nil },
58+ {Add , NewFloat (math .Inf (1 )).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .Inf (1 ), 3 )).ToObject (), nil },
59+ {Add , NewFloat (math .Inf (- 1 )).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .Inf (- 1 ), 3 )).ToObject (), nil },
60+ {Add , NewFloat (math .NaN ()).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .NaN (), 3 )).ToObject (), nil },
61+ {Add , NewComplex (cmplx .NaN ()).ToObject (), NewComplex (3i ).ToObject (), NewComplex (cmplx .NaN ()).ToObject (), nil },
62+ {Add , NewFloat (math .Inf (- 1 )).ToObject (), NewComplex (complex (math .Inf (+ 1 ), 3 )).ToObject (), NewComplex (complex (math .NaN (), 3 )).ToObject (), nil },
63+ {Add , NewComplex (1 + 3i ).ToObject (), None , nil , mustCreateException (TypeErrorType , "unsupported operand type(s) for +: 'complex' and 'NoneType'" )},
64+ {Add , None , NewComplex (1 + 3i ).ToObject (), nil , mustCreateException (TypeErrorType , "unsupported operand type(s) for +: 'NoneType' and 'complex'" )},
65+ {Add , NewInt (3 ).ToObject (), NewComplex (3i ).ToObject (), NewComplex (3 + 3i ).ToObject (), nil },
66+ {Add , NewLong (big .NewInt (9999999 )).ToObject (), NewComplex (3i ).ToObject (), NewComplex (9999999 + 3i ).ToObject (), nil },
67+ {Add , NewFloat (3.5 ).ToObject (), NewComplex (3i ).ToObject (), NewComplex (3.5 + 3i ).ToObject (), nil },
68+ {Sub , NewComplex (1 + 3i ).ToObject (), NewComplex (1 + 3i ).ToObject (), NewComplex (0i ).ToObject (), nil },
69+ {Sub , NewComplex (1 + 3i ).ToObject (), NewComplex (3i ).ToObject (), NewComplex (1 ).ToObject (), nil },
70+ {Sub , NewComplex (1 + 3i ).ToObject (), NewFloat (1 ).ToObject (), NewComplex (3i ).ToObject (), nil },
71+ {Sub , NewComplex (3i ).ToObject (), NewFloat (1.2 ).ToObject (), NewComplex (- 1.2 + 3i ).ToObject (), nil },
72+ {Sub , NewComplex (1 + 3i ).ToObject (), NewComplex (1 + 3i ).ToObject (), NewComplex (0i ).ToObject (), nil },
73+ {Sub , NewComplex (4 + 3i ).ToObject (), NewInt (1 ).ToObject (), NewComplex (3 + 3i ).ToObject (), nil },
74+ {Sub , NewComplex (4 + 3i ).ToObject (), NewLong (big .NewInt (99994 )).ToObject (), NewComplex (- 99990 + 3i ).ToObject (), nil },
75+ {Sub , NewFloat (math .Inf (1 )).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .Inf (1 ), - 3 )).ToObject (), nil },
76+ {Sub , NewFloat (math .Inf (- 1 )).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .Inf (- 1 ), - 3 )).ToObject (), nil },
77+ {Sub , NewComplex (1 + 3i ).ToObject (), None , nil , mustCreateException (TypeErrorType , "unsupported operand type(s) for -: 'complex' and 'NoneType'" )},
78+ {Sub , None , NewComplex (1 + 3i ).ToObject (), nil , mustCreateException (TypeErrorType , "unsupported operand type(s) for -: 'NoneType' and 'complex'" )},
79+ {Sub , NewFloat (math .NaN ()).ToObject (), NewComplex (3i ).ToObject (), NewComplex (complex (math .NaN (), - 3 )).ToObject (), nil },
80+ {Sub , NewComplex (cmplx .NaN ()).ToObject (), NewComplex (3i ).ToObject (), NewComplex (cmplx .NaN ()).ToObject (), nil },
81+ {Sub , NewFloat (math .Inf (- 1 )).ToObject (), NewComplex (complex (math .Inf (- 1 ), 3 )).ToObject (), NewComplex (complex (math .NaN (), - 3 )).ToObject (), nil },
82+ }
83+
84+ for _ , cas := range cases {
85+ switch got , result := checkInvokeResult (wrapFuncForTest (cas .fun ), []* Object {cas .v , cas .w }, cas .want , cas .wantExc ); result {
86+ case checkInvokeResultExceptionMismatch :
87+ t .Errorf ("%s(%v, %v) raised %v, want %v" , getFuncName (cas .fun ), cas .v , cas .w , got , cas .wantExc )
88+ case checkInvokeResultReturnValueMismatch :
89+ if got == nil || cas .want == nil || ! got .isInstance (ComplexType ) || ! cas .want .isInstance (ComplexType ) ||
90+ ! complexesAreSame (toComplexUnsafe (got ).Value (), toComplexUnsafe (cas .want ).Value ()) {
91+ t .Errorf ("%s(%v, %v) = %v, want %v" , getFuncName (cas .fun ), cas .v , cas .w , got , cas .want )
92+ }
93+ }
94+ }
95+ }
96+
4597func TestComplexCompareNotSupported (t * testing.T ) {
4698 cases := []invokeTestCase {
4799 {args : wrapArgs (complex (1 , 2 ), 1 ), wantExc : mustCreateException (TypeErrorType , "no ordering relation is defined for complex numbers" )},
@@ -108,3 +160,11 @@ func TestComplexHash(t *testing.T) {
108160 }
109161 }
110162}
163+
164+ func floatsAreSame (a , b float64 ) bool {
165+ return a == b || (math .IsNaN (a ) && math .IsNaN (b ))
166+ }
167+
168+ func complexesAreSame (a , b complex128 ) bool {
169+ return floatsAreSame (real (a ), real (b )) && floatsAreSame (imag (a ), imag (b ))
170+ }
0 commit comments