2012-05-14 45 views
13

Tôi đang cố gắng tạo ra một vô cùng phức tạp bằng Inf + Inf * j trong đó j là biến phức tạp. Khi tôi làm điều này:Tạo ra vô cùng phức tạp với std :: phức tạp <T> trong C++

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

... 

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

trả lại số phức (NaN + Inf * j).

Nhưng

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

trả về số phức tạp (Inf + 0 * j).

Ngoài ra:

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

trả về số phức tạp (NaN + Inf * j).

Có ai biết điều gì đang xảy ra ở đây không? Bất cứ lúc nào tôi cố gắng để có infinty cho phần tưởng tượng, sau đó NaN được viết trên phần thực.

Ở trên chỉ áp dụng cho các loại hỗ trợ NaN và Infinity tất nhiên. Tôi đang sử dụng g ++ v4.6.1. Tôi đã nhìn vào tiêu đề numeric_limits và không có dấu hiệu cho thấy ở trên nên xảy ra ở tất cả.

Để đưa nội dung trên vào ngữ cảnh, tôi thực sự đang thực hiện ở trên trong một phần chuyên môn hóa của numeric_limits cho phức tạp. Rất cám ơn vì đã xem xét vấn đề này.

TUYỂN DỤNG ĐỂ GỐC BƯU CHÍNH

Tôi đang cung cấp chương trình hoàn chỉnh nhưng ngắn để minh họa sự cố. Tôi cũng đã bao gồm một số thông tin đủ điều kiện về cách chương trình sẽ được biên dịch để tạo ra các kết quả.

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

} 

Biên dịch trên trong g ++ phiên bản 4.6.1 trên Ubuntu với -std = C++ 0x cho kết quả như sau:

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

Nếu không có sự -std = C++ 0x tùy chọn kết quả là:

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

Vì vậy, câu hỏi thực sự là TẠI SAO GNU G ++ V4.6.1 ĐẾN CÂU HỎI THƯỜNG GẶP KHI C++ 0x được chỉ định?

RÀ SOÁT 2 ĐẾN ORIGINAL POST

Tôi chỉ cố gắng sau trong Octave (MATLAB giống như numerics gói):

a = inf + j * inf

Và câu trả lời là:

a = NaN + Infi

Đây chính xác là những gì tôi thấy trong mã C++ 11 (C++ 0x). Tôi không biết Octave được biên dịch với cái gì (đó là sự kết hợp giữa C++ và FORTRAN mà tôi tin) nhưng nếu gói đó trả về kết quả mà tôi nhận được, thì tôi cho rằng đây là hành vi nổi tiếng.

Tuy nhiên, tôi đã xem xét tiêu chuẩn dự thảo C++ 11 và không thể tìm thấy bất kỳ đề cập nào về hành vi này.

RÀ SOÁT 3 ĐẾN ORIGINAL POST

Thêm dòng sau

my_complex_inf.real(my_complex_inf.imag()); 

để ngay sau khi việc xây dựng my_complex_inf trả lại câu trả lời "đúng" (inf, inf) khi biên dịch cho C++ 11. Thật không may, đây là một quá trình 2 bước và tôi không thể tạo ra loại vô hạn phức tạp này trong một hàm constexpr.

+4

Nó hoạt động chính xác [trên g ++ 4.3.4] (http://ideone.com/xfXDo), [g ++ 4.5.1] (http://ideone.com/FpmZK), 4.6.3 và 4.7.0. Vui lòng cung cấp một chương trình mẫu ngắn, hoàn chỉnh. Xem http://sscce.org/. –

+1

Bạn có chắc chắn muốn 4 infinities có thể cho máy bay phức tạp? Tôi sẽ nghĩ rằng bạn sẽ muốn chỉ có một (giống như trong một quả cầu Riemann). –

+1

Vâng, bạn có thể thử '1/std :: complex (0)', vì điều quan trọng duy nhất bạn muốn là '1/infty == 0', nếu bạn đang cố gắng đại diện cho quả cầu Riemann. –

Trả lời

4

Một vô hướng Inf chuyển đổi thành phức tạp là inf + 0 j. Ths là chính xác ở trên. Một vô hướng Inf bù đắp trong mặt phẳng phức tạp ngụ ý aa xoay và, không phải là tính toán, do đó Nan là chính xác. Vấn đề lại là gì?

"Có rồng."

+0

cho phép a = 1 tức là 1 + 0 * j. Một vòng quay của pi/4 là 1 * exp (j * pi/4) tức là sqrt (2) + j * sqrt (2). Nếu a là inf, thì b = inf * exp (j * pi/4). Vì điều này chỉ liên quan đến phép nhân của cả hai phần thực và phức tạp, nên kết quả cũng phải là inf (đối với các phần thực và phức tạp). Vì vậy, tôi không nghĩ rằng nan sẽ nảy sinh từ tính toán quay, nếu đây là cách triển khai. –

4

Bạn đang chạy theo cách mà C++ 11 (và C11) chỉ định số phức và bị nhầm lẫn. Về cơ bản, trong mô hình được chỉ định bởi spec, chỉ có một vô hạn (được biểu diễn bởi (inf, 0)), và cố gắng đặt một 'vô cùng' vào phần ảo của một kết quả phức tạp trong Nan, bởi vì nó không có ý nghĩa trong mô hình đó.

0

Trong đường chính (gcc-4.8) tôi nhận được với -std = C++ 0x (không có -std) câu trả lời mong đợi:

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

gcc-4.6.3 với -std-C++ 11 đưa ra câu trả lời không mong muốn:

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

Tôi nghĩ rằng các nhà xây dựng chỉ nên đặt các loại thực và tưởng tượng theo các đối số tương ứng. Không nên có nan.

Các vấn đề liên quan