2012-05-14 10 views
13

Sto provando a creare un infinito complesso uguale a Inf + Inf * j dove j è la variabile complessa. Quando faccio questo:Creazione di infinito complesso con std :: complex <T> in C++

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

... 

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

restituisce il numero complesso (NaN + Inf * j).

Ma

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

restituisce il numero complesso (Inf + 0 * j).

anche:

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

restituisce il numero complesso (NaN + Inf * j).

Qualcuno sa cosa sta succedendo qui? Ogni volta che tento di avere infinty per la parte immaginaria, allora NaN è scritto sulla parte reale.

Quanto sopra si applica solo ai tipi che supportano NaN e Infinity, naturalmente. Sto usando g ++ v4.6.1. Ho esaminato l'intestazione numeric_limits e non vi è alcuna indicazione che ciò debba accadere.

Per mettere il contesto sopra riportato, in realtà sto facendo quanto sopra in una specializzazione parziale di numeric_limits per il complesso. Molte grazie per aver considerato questo problema.

REVISIONE allarticolo originale

sto fornendo un programma completo, ma a breve per illustrare il problema. Ho anche incluso alcune informazioni aggiuntive su come compilare il programma per generare i risultati.

#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; 

} 

compilazione quanto sopra in g ++ versione 4.6.1 su Ubuntu con il -std = C++ 0x dà i seguenti risultati:

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

Senza il -std = C++ 0x opzione risultati sono:

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

Quindi la domanda è davvero PERCHÉ GNU g ++ V4.6.1 dare le risposte fa quando C++ 0x SPECIFICATO?

REVISIONE 2 allarticolo originale

Ho appena provato quanto segue in Octave (MATLAB come pacchetto numerici):

a = inf + j * inf

E la risposta è:

a = NaN + Infi

Questo è esattamente ciò che vedo nel mio codice C++ 11 (C++ 0x). Non so con cosa Octave sia compilato (è una combinazione di C++ e FORTRAN credo) ma se quel pacchetto restituisce il risultato che sto ottenendo, allora presumo che questo sia un comportamento ben noto.

Tuttavia, ho esaminato lo standard di bozza C++ 11 e non riesco a trovare alcuna menzione di questo comportamento.

Revisione 3 allarticolo originale

Aggiungendo la seguente riga

my_complex_inf.real(my_complex_inf.imag()); 

a poco dopo la costruzione my_complex_inf restituire la risposta "corretta" (inf, inf) se compilato per C++ 11. Sfortunatamente, questo è ora un processo in 2 fasi e non riesco a creare questo tipo di infinito complesso in una funzione di constexpr.

+4

Funziona correttamente [su g ++ 4.3.4] (http://ideone.com/xfXDo), [g ++ 4.5.1] (http://ideone.com/FpmZK), 4.6.3 e 4.7.0. Si prega di fornire un breve programma completo di esempio. Vedi http://sscce.org/. –

+1

Sei sicuro di volere 4 infiniti possibili per il piano complesso? Penserei che ne vorresti solo uno (come in una sfera di Riemann). –

+1

Bene, puoi provare '1/std :: complex (0)', poiché l'unica cosa importante che vorresti è '1/infty == 0', se stai cercando di rappresentare la sfera di Riemann. –

risposta

4

Uno scalare Inf convertito in complesso è inf + 0 j. È corretto sopra. Un offset Inf scalare nel piano complesso implica una rotazione e, non è calcolabile, quindi Nan è corretto. Qual è il problema di nuovo?

"Ci sono i draghi."

+0

let a = 1 cioè 1 + 0 * j. Una rotazione di pi/4 è 1 * exp (j * pi/4) cioè sqrt (2) + j * sqrt (2). Se a è inf, allora b = inf * exp (j * pi/4). Dal momento che questo comporta solo moltiplicazione di inf di entrambe le parti reali e complessi, quindi il risultato dovrebbe essere inf (per le parti reali e complessi.) Quindi non credo che nan nasca dal calcolo di una rotazione, se questo è come è implementato. –

4

Si sta eseguendo il modo in cui C++ 11 (e C11) specificano numeri complessi e si confondono.

Fondamentalmente, nel modello richiesto dalla specifica, c'è solo un infinito (rappresentato da (inf, 0)) e tenta di inserire un 'infinito' nella parte immaginaria di un risultato complesso in Nan, perché non ha senso in quel modello.

0

In linea principale (gcc-4.8) ottengo con -std = C++ 0x the (senza -std) risposta attesa:

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

gcc-4.6.3 con -std-C++ 11 dà la risposta inaspettata:

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

Penso che i costruttori dovrebbero semplicemente impostare i tipi reali e immaginari secondo gli argomenti corrispondenti. Non ci dovrebbero essere nan.