用fft计算大数乘法c语言,FFT用于高效大数乘法(当模板用)

#include

#include

#include

#include

using namespace std;

const double PI(acos(-1.0));

typedef complex C;

const int N = (1 << 20);

int ans[N];

C a[N], b[N];

char s[N], t[N];

void bit_reverse_swap(C* a, int n) {

for (int i = 1, j = n >> 1, k; i < n - 1; ++i) {

if (i < j) swap(a[i], a[j]);

// tricky

for (k = n >> 1; j >= k; j -= k, k >>= 1)  // inspect the highest "1"

;

j += k;

}

}

void FFT(C* a, int n, int t) {

bit_reverse_swap(a, n);

for (int i = 2; i <= n; i <<= 1) {

C wi(cos(2.0 * t * PI / i), sin(2.0 * t * PI / i));

for (int j = 0; j < n; j += i) {

C w(1);

for (int k = j, h = i >> 1; k < j + h; ++k) {

C t = w * a[k + h], u = a[k];

a[k] = u + t;

a[k + h] = u - t;

w *= wi;

}

}

}

if (t == -1) {

for (int i = 0; i < n; ++i) {

a[i] /= n;

}

}

}

int trans(int x) {

return 1 << int(ceil(log(x) / log(2) - 1e-9));  // math.h/log() 以e为底

}

int main() {

//  freopen("test0.in","r",stdin);

// freopen("test0b.out","w",stdout);

int n, m, l;

for (; ~scanf("%s%s", s, t);) {

n = strlen(s);

m = strlen(t);

l = trans(n + m - 1);  // n次*m次不超过n+m-1次

for (int i = 0; i < n; ++i) a[i] = C(s[n - 1 - i] - '0');

for (int i = n; i < l; ++i) a[i] = C(0);

for (int i = 0; i < m; ++i) b[i] = C(t[m - 1 - i] - '0');

for (int i = m; i < l; ++i) b[i] = C(0);

FFT(a, l, 1);  //把A和B换成点值表达

FFT(b, l, 1);

for (int i = 0; i < l; ++i)  //点值做乘法

a[i] *= b[i];

FFT(a, l, -1);  //逆DFT

for (int i = 0; i < l; ++i) ans[i] = (int)(a[i].real() + 0.5);

ans[l] = 0;  // error-prone :'l' -> '1'

for (int i = 0; i < l; ++i) {

ans[i + 1] += ans[i] / 10;

ans[i] %= 10;

}

int p = l;

for (; p && !ans[p]; --p)

;

for (; ~p; putchar(ans[p--] + '0'))

;

puts("");

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FFT(快速傅里叶变换)是一种用来计算离散傅里叶变换(DFT)的算法,可以将时域信号转换为频域信号。在C语言中,我们可以使用一些现成的库函数来实现FFT计算频率。 首先,需要导入相应的库函数。例如,在C语言中,我们可以使用fftw库函数来实现FFT计算频率。可以通过以下方式导入该库函数: ```c #include <fftw3.h> ``` 接下来,我们需要定义所需的变量和数组。通常,我们需要一个输入数组来存储时域信号,一个输出数组来存储频域信号,并定义FFT所需的一些参数。 ```c #define N 1024 // 数组的大小 fftw_complex *in, *out; // 输入和输出数组 fftw_plan p; // FFT计划 ``` 然后,我们需要为输入数组和输出数组分配内存,并创建一个FFT计划。 ```c in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); ``` 接下来,我们可以将时域信号存储在输入数组中。 ```c for (int i = 0; i < N; i++) { // 将时域信号存储在输入数组中 in[i][0] = time_domain_signal[i]; in[i][1] = 0; } ``` 然后,我们可以执行FFT计算。 ```c fftw_execute(p); ``` 最后,我们可以从输出数组中获取频域信号,即计算得到的频率。 ```c for (int i = 0; i < N/2; i++) { // 获取频率 double frequency = (double)i / (double)N * sample_rate; // 输出频率 printf("Frequency %d: %lf\n", i, frequency); } ``` 需要注意的是,FFT计算得到的频域信号是将频率分成了N/2个区间,对应的频率可以通过i / N * sample_rate计算得到。其中,sample_rate表示采样率,即每秒采集的样本数。 以上是使用C语言实现FFT计算频率的基本步骤,你可以根据实际需求进行进一步的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值