operator* of std::complex returns different answer than manual formula of complex number multiplication

Viewed 56

I'm running the following code:

complex<int16_t> num1 (953, -20068);
complex<int16_t> num2 (953, -20068);
complex<int32_t> result;
result = num1*num2;
std::cout << to_string(result.real()) << "+" << to_string(result.imag())  << "i"<< std::endl;

I get the following result:

-15199+23416i

But if I calculate the multiplication according to the formula of multiplication of complex numbers:

complex<int16_t> num1 (953, -20068);
complex<int16_t> num2 (953, -20068);

int32_t A = ((num1.real())*(num2.real()))-((num1.imag())*(num2.imag()));
int32_t B = ((num1.real())*(num2.imag()))+((num2.real())*(num1.imag()));

std::cout << to_string(A) << to_string(B)  << "i"<< std::endl;

I get the following result:

-401816415-38249608i

My question is why the formula of multiplying complex numbers returns a different result from that of the oprator* (of the type std::complex)?

2 Answers

Your complex numbers are of type complex<int16_t>, meaning the real and imaginary parts are both 16 bits. The result of multiplying them must also have real and imaginary parts of 16 bits. This happens before you store the result into a complex<int32_t>.

When you do the multiplication yourself, the 16 bit values are first converted to ints (which are likely 32 bits on your system). Thus your results aren't truncated when you put them into int32_ts.

You can fix this by using complex<int32_t> values all around, or by doing the multiplication using complex<int32_t>s instead:

result = complex<int32_t>(num1) * complex<int32_t>(num2)

Your inputs are int16_t, so you're most likely getting overflow, since the result will also be int16_t. Only after the result has been calculated will it be converted into an int32_t.

If you change your inputs to std::complex<int32_t> the result will be correct.

Related