Подтвердить что ты не робот

Создание сложной бесконечности с помощью std:: complex <T> в С++

Я пытаюсь создать сложную бесконечность, равную Inf + Inf * j, где j - комплексная переменная. Когда я это сделаю:

#include <complex>
#include <limits>
using std;

...

complex<double> attempt1 =
   complex<double>( numeric_limits<double>::infinity(),
                    numeric_limits<double>::infinity() );

возвращает комплексное число (NaN + Inf * j).

Но

complex<double> attempt2 =
   complex<double>( numeric_limits<double>::infinity() );

возвращает комплексное число (Inf + 0 * j).

Также:

complex<double> attempt_at_imag_inf =
   complex<double>(any_value_here, numeric_limits<double>::infinity());

возвращает комплексное число (NaN + Inf * j).

Кто-нибудь знает, что здесь происходит? Каждый раз, когда я пытаюсь получить интимность для воображаемой части, тогда NaN записывается на реальной части.

Вышеуказанное относится только к типам, которые поддерживают NaN и Infinity. Я использую g++ v4.6.1. Я просмотрел заголовок numeric_limits, и нет никаких указаний на то, что это должно произойти вообще.

Чтобы перевести это в контекст, я на самом деле делаю это в частичной специализации numeric_limits для сложного. Большое спасибо за рассмотрение этой проблемы.

ПЕРЕСМОТР К ОРИГИНАЛЬНОЙ ПОЧТЕ

Я предоставляю полную, но короткую программу, чтобы проиллюстрировать эту проблему. Я также включил некоторую дополнительную квалификационную информацию о том, как программа должна быть скомпилирована для генерации результатов.

#include <iostream>
#include <complex>
#include <limits>

using namespace std;

int main(int argc, char* argv[])
{

   complex<double> my_complex_inf =
      complex<double>(numeric_limits<double>::infinity(),
                      numeric_limits<double>::infinity());

   cout << "my_complex_inf = " << my_complex_inf << endl;

   complex<double> attempt2 =
      complex<double>( numeric_limits<double>::infinity() );

   cout << "attempt2 = " << attempt2 << endl;

   double any_value_here = 0;

   complex<double> attempt_at_imag_inf =
      complex<double>(0, numeric_limits<double>::infinity());

   cout << "attempt_at_imag_inf = " << attempt_at_imag_inf << endl;

   return 0;

}

Компиляция выше в g++ версии 4.6.1 на Ubuntu с -std = С++ 0x дает следующие результаты:

my_complex_inf = (nan,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (nan,inf)

Без опции -std = С++ 0x результаты:

my_complex_inf = (inf,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (0,inf)

Итак, действительно вопрос: ПОЧЕМУ GNU g++ V4.6.1 ДАЙТЕ ОТВЕТЫ, КОГДА ЛИ КОГДА С++ 0x УКАЗАН?

ПЕРЕСМОТР 2 К ОРИГИНАЛЬНОЙ ПОЧТЕ

Я просто попробовал следующее в Octave (MATLAB-подобный пакет чисел):

a = inf + j * inf

И ответ:

a = NaN + Infi

Это именно то, что я вижу в своем коде С++ 11 (С++ 0x). Я не знаю, с чем скомпилирован Octave (это сочетание С++ и FORTRAN, я верю), но если этот пакет возвращает результат, который я получаю, то я предполагаю, что это хорошо известное поведение.

Однако я рассмотрел проект стандарта С++ 11 и не могу найти упоминания об этом поведении.

ПЕРЕСМОТР 3 К ОРИГИНАЛЬНОЙ ПОЧТЕ

Добавление следующей строки

my_complex_inf.real(my_complex_inf.imag());

сразу после построения my_complex_inf возвращает "правильный" ответ (inf, inf) при компиляции для С++ 11. К сожалению, теперь это двухэтапный процесс, и я не могу создать такую ​​сложную бесконечность в функции constexpr.

4b9b3361

Ответ 1

Скаляр Inf преобразуется в комплекс inf + 0 j. Это верно выше. Скалярное смещение Inf в комплексной плоскости влечет за собой поворот и, не вычисляется, поэтому Nan является правильным. В чем проблема снова?

"Там будут драконы".

Ответ 2

Вы сталкиваетесь с тем, что С++ 11 (и C11) задает сложные номера и путается.

В принципе, в модели, заданной спецификацией, существует только одна бесконечность (представленная (inf, 0)), и попытки поместить "бесконечность" в мнимую часть сложного результата в Nan, поскольку это делает нет смысла в этой модели.

Ответ 3

В mainline (gcc-4.8) я получаю с -std = С++ 0x ожидаемый (no -std) ответ:

my_complex_inf = (inf,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (0,inf)

gcc-4.6.3 с -std-С++ 11 дает неожиданный ответ:

my_complex_inf = (-nan,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (-nan,inf)

Я думаю, что конструкторы должны просто установить действительный и мнимый типы в соответствии с соответствующими аргументами. Не должно быть nan.