C++实现的基-2迭代Cooley-Tukey FFT支持复数输入、自然序输出,含位逆序重排与蝶形运算,要求长度为2的幂,使用std::complex,无外部依赖,可直接编译运行。

用 C++ 实现一个高效、可读、实用的快速傅里叶变换(FFT),核心是采用 基-2 递归/迭代 Cooley-Tukey 算法,支持复数输入,输出为标准频域复数数组(按自然序,非位逆序)。下面给出一个轻量、无外部依赖、可直接编译运行的完整实现。
基础准备:使用 std::complex 和标准库
无需第三方库,仅需:
-
#include和#include - 使用
std::complex表示复数 - 输入长度必须是 2 的整数次幂(自动补零或报错提示)
迭代版 FFT(推荐:避免递归开销,内存友好)
迭代实现更稳定、无栈溢出风险,适合实时信号处理。关键点是位逆序重排 + 蝶形运算分层计算:
立即学习“C++免费学习笔记(深入)”;
#include#include #include #include using Complex = std::complex
using VecC = std::vector // 将 n 转换为 bit-reversed 数(bit width = log2(size)) int bitReverse(int n, int bits) { int rev = 0; for (int i = 0; i < bits; ++i) { rev |= ((n >> i) & 1) << (bits - 1 - i); } return rev; }
// 基-2 迭代 FFT(in-place,升序输出) void fft(VecC& x) { int N = x.size(); if (N <= 1) return;
// 检查是否为 2 的幂 if ((N & (N - 1)) != 0) { throw std::runtime_error("FFT size must be power of 2"); } int bits = 0; for (int n = N; n youjiankuohaophpcn 1; n youjiankuohaophpcnyoujiankuohaophpcn= 1) ++bits; // 位逆序重排 for (int i = 0; i zuojiankuohaophpcn N; ++i) { int j = bitReverse(i, bits); if (j youjiankuohaophpcn i) std::swap(x[i], x[j]); } // 蝶形运算:按级数(m = 1,2,4,...,N/2) for (int m = 1; m zuojiankuohaophpcn N; m *= 2) { double theta = M_PI / m; // π/m Complex w_m = Complex(cos(theta), -sin(theta)); // 主根 ωₘ for (int k = 0; k zuojiankuohaophpcn N; k += 2 * m) { Complex w = 1.0; for (int j = 0; j zuojiankuohaophpcn m; ++j) { Complex t = w * x[k + j + m]; Complex u = x[k + j]; x[k + j] = u + t; x[k + j + m] = u - t; w *= w_m; } } }}
使用示例:生成正弦信号并分析频谱
验证 FFT 正确性,比如对 64 点含 8Hz 正弦波(采样率 64Hz)做变换:
立即学习“C++免费学习笔记(深入)”;
int main() { const int N = 64; VecC signal(N);// 生成 8Hz 正弦(采样率 fs = 64Hz → 一个周期 8 点 → 频点索引 = 8) double fs = 64.0; for (int i = 0; i zuojiankuohaophpcn N; ++i) { double t = i / fs; signal[i] = std::sin(2 * M_PI * 8 * t); } fft(signal); // 输出前 12 个幅度谱(|X[k]|) std::cout zuojiankuohaophpcnzuojiankuohaophpcn "Magnitude spectrum (first 12 bins):\n"; for (int k = 0; k zuojiankuohaophpcn 12; ++k) { double mag = std::abs(signal[k]); std::cout zuojiankuohaophpcnzuojiankuohaophpcn "bin[" zuojiankuohaophpcnzuojiankuohaophpcn k zuojiankuohaophpcnzuojiankuohaophpcn "] = " zuojiankuohaophpcnzuojiankuohaophpcn mag zuojiankuohaophpcnzuojiankuohaophpcn "\n"; } // 应看到 bin[8] 和 bin[56](共轭对)幅值显著(≈32) return 0;}
补充说明与优化建议
- 逆变换 IFFT:只需对 FFT 结果取共轭 → 调用 fft → 再取共轭并除以 N
- 实数 FFT 优化:若输入纯实数,可用 packed 格式(如将两个实序列合进一个复序列)提升 2 倍效率
- 精度注意:使用
double复数,避免float在长序列下累积误差- 生产环境:高频/大数据推荐用 FFTW 或 Intel IPP;教学/嵌入式场景此实现足够清晰可控
基本上就这些 —— 代码简洁、逻辑清晰、可直接集成到信号采集、滤波器设计或频谱分析模块中。需要支持任意长度(Bluestein 算法)或 SIMD 加速时,再在此基础上扩展即可。










