std::complex
出自 cppreference.com
| 定義於標頭 <complex> |
||
| template< class T > class complex; |
(1) | |
| template<> class complex<float>; |
(2) | (至 C++23 止) |
| template<> class complex<double>; |
(3) | (至 C++23 止) |
| template<> class complex<long double>; |
(4) | (至 C++23 止) |
用於表示與操作複數的 std::complex 特化版本,對於 cv 未限定的 標準(C++23 前) 浮點類型,它們是 TriviallyCopyable(C++23 起) 字面類型 (LiteralType)。
目錄 |
[編輯] 模板參數
| T | - | 實部與虛部的類型。若 T 不是 cv 未限定的 標準(C++23 前) 浮點類型,則行為未指定(且可能編譯失敗);若 T 不是 數值類型 (NumericType),則行為未定義。 |
[編輯] 成員類型
| 成員型別 | 定義 |
value_type
|
T
|
[編輯] 成員函數
| 建構一個複數 (公開成員函數) | |
| 賦值內容 (公開成員函數) | |
| 存取複數的實部 (公開成員函數) | |
| 存取複數的虛部 (公開成員函數) | |
| 兩個複數,或一個複數與一個純量之間的複合賦值 (公開成員函數) |
[編輯] 非成員函數
| 對複數套用一元運算子 (函式模板) | |
| 對兩個複數值或一個複數與一個純量執行複數算術運算 (函式模板) | |
| (於 C++20 中移除) |
比較兩個複數或一個複數與一個純量 (函式模板) |
| 序列化與反序列化複數 (函式模板) | |
| (C++26) |
從 std::complex 獲取實部或虛部的參考 (函數模板) |
| 返回實部 (函數模板) | |
| 返回虛部 (函數模板) | |
| 返回複數的模(magnitude) (函數模板) | |
| 返回相位角(phase angle) (函數模板) | |
| 返回模的平方 (函數模板) | |
| 返回複共軛 (函數模板) | |
| (C++11) |
返回在黎曼球上的投影 (函數模板) |
| 由模與相位角建構複數 (函數模板) | |
指數函式 | |
| 複數以 e 為底的指數 (函數模板) | |
| 複數自然對數,分支切割(branch cuts)位於負實軸上 (函數模板) | |
| 複數常用對數,分支切割位於負實軸上 (函數模板) | |
冪函式 | |
| 複數冪,參數之一或兩者皆可為複數 (函數模板) | |
| 複數平方根,範圍在右半平面 (函數模板) | |
三角函式 | |
| 計算複數的正弦 (sin(z)) (函數模板) | |
| 計算複數的餘弦 (cos(z)) (函數模板) | |
| 計算複數的正切 (tan(z)) (函數模板) | |
| (C++11) |
計算複數的反正弦 (arcsin(z)) (函數模板) |
| (C++11) |
計算複數的反餘弦 (arccos(z)) (函數模板) |
| (C++11) |
計算複數的反正切 (arctan(z)) (函數模板) |
雙曲函式 | |
| 計算複數的雙曲正弦 (sinh(z)) (函數模板) | |
| 計算複數的雙曲餘弦 (cosh(z)) (函數模板) | |
| 計算複數的雙曲正切 (tanh(z)) (函數模板) | |
| (C++11) |
計算複數的反雙曲正弦 (arsinh(z)) (函數模板) |
| (C++11) |
計算複數的反雙曲餘弦 (arcosh(z)) (函數模板) |
| (C++11) |
計算複數的反雙曲正切 (artanh(z)) (函數模板) |
[編輯] 輔助類型
| 獲取 std::complex 的大小 (類模板特化) | |
| 獲取 std::complex 的底層實部與虛部數值類型 (類模板特化) |
[編輯] 陣列導向存取
對於任何 std::complex<T> 類型的物件 z,reinterpret_cast<T(&)[2]>(z)[0] 為 z 的實部,而 reinterpret_cast<T(&)[2]>(z)[1] 為 z 的虛部。
對於任何指向 std::complex<T> 陣列元素的指標 p 以及任何有效的陣列索引 i,reinterpret_cast<T*>(p)[2 * i] 為複數 p[i] 的實部,而 reinterpret_cast<T*>(p)[2 * i + 1] 為複數 p[i] 的虛部。
此要求的目的是為了維護 C++ 程式庫複數類型與 C 語言複數類型(及其陣列)之間的二進位相容性,後者具有相同的物件表示要求。
[編輯] 實作註解
為了滿足陣列導向存取的要求,實作必須將 std::complex 特化版本的實部與虛部儲存在分離且相鄰的記憶體位置。其非靜態資料成員的可能宣告包括:
- 一個類型為
value_type[2]的陣列,第一個元素儲存實部,第二個元素儲存虛部(例如:Microsoft Visual Studio); - 一個類型為
value_type _Complex的單一成員(封裝了對應的 C 語言複數類型)(例如:GNU libstdc++); - 兩個類型為
value_type的成員,具有相同的成員存取權限,分別儲存實部與虛部(例如:LLVM libc++)。
實作不能宣告額外的非靜態資料成員,以免佔用與實部及虛部不連續的儲存空間,並必須確保類模板特化版本不包含任何 填充位元 (padding bit)。實作也必須確保針對陣列存取的優化考量到指向 value_type 的指標可能會別名 (aliasing) 於 std::complex 特化版本或其陣列的可能性。
[編輯] 字面量
| 定義於內聯命名空間
std::literals::complex_literals | |
| 表示純虛數的 std::complex 字面量 (函式) | |
[編輯] 附註
| 功能測試巨集 | 數值 | 標準 | 功能 |
|---|---|---|---|
__cpp_lib_constexpr_complex |
201711L |
(C++20) | <complex> 中的 constexpr 簡易複數數學函數 |
202306L |
(C++26) | <complex> 的更多 constexpr 支援 | |
__cpp_lib_tuple_like |
202311L |
(C++26) | 為 std::complex 加入 tuple 協定 |
[編輯] 範例
執行此程式碼
#include <cmath> #include <complex> #include <iomanip> #include <iostream> #include <ranges> int main() { using namespace std::complex_literals; std::cout << std::fixed << std::setprecision(1); std::complex<double> z1 = 1i * 1i; // imaginary unit squared std::cout << "i * i = " << z1 << '\n'; std::complex<double> z2 = std::pow(1i, 2); // imaginary unit squared std::cout << "pow(i, 2) = " << z2 << '\n'; const double PI = std::acos(-1); // or std::numbers::pi in C++20 std::complex<double> z3 = std::exp(1i * PI); // Euler's formula std::cout << "exp(i * pi) = " << z3 << '\n'; std::complex<double> z4 = 1.0 + 2i, z5 = 1.0 - 2i; // conjugates std::cout << "(1 + 2i) * (1 - 2i) = " << z4 * z5 << '\n'; const auto zz = {0.0 + 1i, 2.0 + 3i, 4.0 + 5i}; #if __cpp_lib_tuple_like >= 202311L for (double re : zz | std::views::keys) std::cout << re << ' '; std::cout << '\n'; for (double im : zz | std::views::values) std::cout << im << ' '; std::cout << '\n'; #else for (double re : zz | std::views::transform([](auto z){ return z.real(); })) std::cout << re << ' '; std::cout << '\n'; for (double im : zz | std::views::transform([](auto z){ return z.imag(); })) std::cout << im << ' '; std::cout << '\n'; #endif }
輸出
i * i = (-1.0,0.0) pow(i, 2) = (-1.0,0.0) exp(i * pi) = (-1.0,0.0) (1 + 2i) * (1 - 2i) = (5.0,0.0) 0.0 2.0 4.0 1.0 3.0 5.0
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯應用於之前的 C++ 標準。
| DR | 應用於 | 出版時的行為 | 正確的行為 |
|---|---|---|---|
| LWG 387 | C++98 | std::complex 未保證與 C 語言的 complex 相容 |
保證相容 |
[編輯] 參見
| C 文件 關於 複數運算
|