оператор * std::complex возвращает ответ, отличный от ручной формулы умножения комплексных чисел

#c #complex-numbers

#c #комплексные числа

Вопрос:

Я запускаю следующий код:

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

Я получаю следующий результат:

 -15199 23416i
  

Но если я вычисляю умножение в соответствии с формулой умножения комплексных чисел:

 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;
  

Я получаю следующий результат:

 -401816415-38249608i
  

Мой вопрос в том, почему формула умножения комплексных чисел возвращает результат, отличный от результата оператора * (типа std::complex)?

Комментарии:

1. Потому int16_t что может содержать только значения от -32768 до 32767. Измените тип на complex<int32_t> , и он будет работать нормально

2. Это не решает вопрос, но эти вызовы to_string не нужны. Это делает программа вставки потока.

Ответ №1:

Ваши комплексные числа имеют тип complex<int16_t> , то есть действительная и мнимая части равны 16 битам. Результат их умножения также должен иметь действительную и мнимую части по 16 бит. Это происходит до того, как вы сохраните результат в a complex<int32_t> .

Когда вы выполняете умножение самостоятельно, 16-битные значения сначала преобразуются в int s (которые, вероятно, составляют 32 бита в вашей системе). Таким образом, ваши результаты не усекаются, когда вы помещаете их в int32_t s .

Вы можете исправить это, используя complex<int32_t> значения повсюду или выполняя умножение с использованием complex<int32_t> s вместо этого:

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

Ответ №2:

Ваши входные int16_t данные, так что вы, скорее всего, получаете переполнение, поскольку результат также будет int16_t . Только после вычисления результата он будет преобразован в int32_t .

Если вы измените свои входные данные std::complex<int32_t> , результат будет правильным.