找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 5038|回复: 7

大数乘法c源码 -fft

[复制链接]
发表于 2016-7-28 23:38:46 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
本帖最后由 Ayala 于 2016-7-28 23:39 编辑

用c写代码对我来说好痛苦!


  1. double sin(double x);
  2. double cos(double x);

  3. double acos(double x);
  4. double fmod(double x,double y);
  5. double fabs(double x);
  6. double floor(double x);
  7. double ceil(double x);



  8. typedef struct
  9. {
  10.         double real;
  11.         double img;
  12. }complex;

  13. #ifdef cp
  14. #undef cp
  15. typedef complex cp;
  16. #else
  17. typedef complex cp;
  18. #endif

  19. #ifndef max
  20. #define max(a,b) (((a) > (b)) ? (a) : (b))
  21. #endif

  22. #define N 1<<16


  23. __int64 a[N];
  24. __int64 b[N];
  25. __int64 c[N<<1];
  26. double cc[N<<1];
  27. double PI;

  28. const int LEN = 2, MOD = 100;
  29. const double MODf = 100.0;


  30. #ifdef x86_xp
  31. #ifndef _ftol2

  32. __int64 _ftol2(double x)
  33. {
  34.   __int16 e,ee;
  35.   __int64 r;
  36.   __asm
  37.   {
  38.     fld qword ptr x
  39.    
  40.     fstsw word ptr [ee]
  41.     mov ax,word ptr [ee]
  42.     or ah,0xc
  43.     mov word ptr [e],ax
  44.    
  45.     fldcw word ptr [e]
  46.     fistp qword ptr [r]
  47.     fldcw word ptr [ee]
  48.    
  49.     mov eax,dword ptr [r]
  50.     mov edx,dword ptr [r+4]
  51.   }
  52. }
  53. #endif
  54. #endif

  55. void   add(complex   a,complex   b,complex   *c)      
  56. {
  57.   //_fpreset();
  58.         c->real        =a.real        +        b.real;      
  59.         c->img        =a.img        +        b.img;      
  60. }

  61. void   sub(complex   a,complex   b,complex   *c)      
  62. {
  63.   //_fpreset();
  64.         c->real=a.real-b.real;      
  65.         c->img=a.img-b.img;      
  66. }

  67. void   mul(complex   a,complex   b,complex   *c)      
  68. {      
  69.   //_fpreset();
  70.         c->real        =a.real*b.real  -   a.img*b.img;      
  71.         c->img        =a.real*b.img   +   a.img*b.real;      
  72. }      


  73. void   divi(complex   a,complex   b,complex   *c)      
  74. {      
  75.   //_fpreset();
  76.         c->real        =(a.real*b.real+a.img*b.img)/(b.real*b.real+b.img*b.img);      
  77.         c->img        =(a.img*b.real-a.real*b.img)/(b.real*b.real+b.img*b.img);
  78. }       

  79.    
  80. void bit_reverse_copy(cp a[], int n, cp b[])   
  81. {   
  82.     int i, j, k, u, m;   
  83.     for (u = 1, m = 0; u < n; u <<= 1, ++m);   
  84.     for (i = 0; i < n; ++i)   
  85.     {   
  86.         j = i; k = 0;   
  87.         for (u = 0; u < m; ++u, j >>= 1)   
  88.             k = (k << 1) | (j & 1);   
  89.         b[k] = a[i];   
  90.         //printf("b[%d]=%.2lf+%.2lfi\n",k,b[k].real,b[k].img);
  91.     }   
  92. }



  93. void FFT(cp _x[], int n, int flag)   
  94. {   
  95.     static cp x[N << 1]={0.0};   
  96.     int i, j, k, kk, p, m;   
  97.     double alpha;   
  98.    
  99.     cp wn,w,u,t,up,down;
  100.     //_fpreset();
  101.    
  102.     bit_reverse_copy(_x, n, x);
  103.    
  104.     alpha = 2.0 * acos(-1.0);
  105.     if (flag) alpha = -alpha;   
  106.    
  107.     for (i = 1, m = 0; i < n; i <<= 1, ++m);   
  108.    
  109.     for (i = 0, k = 2; i < m; ++i, k <<= 1)   
  110.     {   
  111.         wn.real = cos(alpha / k);
  112.         wn.img  = sin(alpha / k);
  113.         for (j = 0; j < n; j += k)   
  114.         {   
  115.             w.real = 1.0;  
  116.             w.img  = 0.0;
  117.             kk = k >> 1;   
  118.             for (p = 0; p < kk; ++p)   
  119.             {      
  120.                 mul(w, x[j + p + kk],&t);
  121.                 add(x[j + p],t,&up);
  122.                 sub(x[j + p],t,&down);
  123.                
  124.                 x[j + p]      = up;   
  125.                 x[j + p + kk] = down;   
  126.                
  127.                 mul(w,wn,&u);
  128.                 w = u;   
  129.             }   
  130.         }   
  131.     }   
  132.     memcpy(_x, x, sizeof(cp) * n);   
  133. }   


  134. void polynomial_multiply(__int64 a[], int na, __int64 b[], int nb, __int64 c[], int *nc)   
  135. {   
  136.     static cp x[N << 1], y[N << 1],u[N << 1];
  137.     int i, n;
  138.     //_fpreset();
  139.     i = max(na, nb) << 1;   
  140.     for (n = 1; n < i; n <<= 1);
  141.    
  142.     for (i = 0; i < na; ++i)
  143.     {
  144.       x[i].real = a[i];  
  145.       x[i].img  = 0;
  146.       //printf("x[%i]=%.2lf+%.2lfi\n",i,x[i].real,x[i].img);
  147.     }
  148.    
  149.     for (; i < n; ++i)
  150.     {
  151.       x[i].real = 0;   
  152.       x[i].img  = 0;
  153.     }
  154.    
  155.     FFT(x, n, 0);   
  156.    
  157.    
  158.     for (i = 0; i < nb; ++i)
  159.     {
  160.       y[i].real = b[i];   
  161.       y[i].img  = 0;
  162.       //printf("y[%i]=%.2lf+%.2lfi\n",i,y[i].real,y[i].img);
  163.     }
  164.    
  165.     for (; i < n; ++i)
  166.     {
  167.       y[i].real = 0;   
  168.       y[i].img  = 0;
  169.     }
  170.    
  171.     FFT(y, n, 0);   
  172.    
  173.     for (i = 0; i < n; ++i)
  174.     {
  175.       //printf("x[%i]=%.2lf+%.2lfi\n",i,x[i].real,x[i].img);
  176.       //printf("y[%i]=%.2lf+%.2lfi\n",i,y[i].real,y[i].img);
  177.       mul(x[i],y[i],&u[i]);   
  178.       //printf("u[%i]=%.2lf+%.2lfi\n",i,u[i].real,u[i].img);
  179.     }
  180.    
  181.     FFT(u, n, 1);   
  182.    
  183.     for (i = 0; i < n; ++i)     
  184.     {   
  185.         //printf("c[%d] .lf = %.53lf\n",i,u[i].real / n + 0.5);
  186.         c[i] = _ftol2(u[i].real / n + 0.5);  
  187.         //printf("c[%d]  I64d = %I64d\n",i,c[i]);
  188.     }   
  189.     for (i = na + nb - 1; i > 1 && !c[i - 1]; --i);
  190.     *nc = i;
  191. }   


  192. void convert(char *s, __int64 a[], int * n)   
  193. {   
  194.     int len = strlen(s), i, j, k,r;
  195.     for (r = 0, i = len - LEN; i >= 0; i -= LEN)   
  196.     {   
  197.         for (j = k = 0; j < LEN; ++j)  
  198.         {  
  199.             k = k * 10 + (s[i + j] - '0');   
  200.         }
  201.         a[r++] = k;   
  202.         //printf("@207 k = %d\n",k);
  203.     }   
  204.     i += LEN;   
  205.     if (i)   
  206.     {   
  207.         for (j = k = 0; j < i; ++j)
  208.         {
  209.             k = k * 10 + (s[j] - '0');   
  210.         }
  211.         a[r++] = k;   
  212.         //printf("@217 k = %d\n",k);
  213.     }   
  214.     *n=r;
  215.     //printf("@220 r = %d\n",r);
  216. }   
  217.    
  218. void print(__int64 a[], int n)   
  219. {   
  220.     printf("%I64d", a[--n]);   
  221.     while (n) printf("%02I64d", a[--n]);   
  222.     puts("");   
  223. }   


  224. char buf[N + 10];   

  225. #ifndef EOF
  226.   #define EOF (-1)
  227. #endif

  228. #ifndef false
  229.   #define false 0
  230. #endif

  231. #ifndef true
  232.   #define true 1
  233. #endif


  234. /*
  235. void conc()
  236. {
  237.   
  238.   SetConsoleCP(936);
  239.   SetConsoleOutputCP(936);
  240.   SetConsoleMode(GetStdHandle(-10),0x7F);//STD_INPUT_HANDLE
  241. }
  242. */

  243. int mainCRTStartup()   
  244. {   
  245.     int i,na, nb, nc,sign,e;   
  246.     __int64 t1, t2;   
  247.     double f1,f2;
  248.         
  249.     //conc();
  250.     printf("******************************************************\n");
  251.     printf("*                                                    *\n");
  252.     printf("******************************************************\n");
  253.     while (scanf("%s", buf) != EOF)   
  254.     {   
  255.         sign = false;   
  256.         if (buf[0] == '-')   
  257.         {   
  258.             sign = !sign;     
  259.             convert(buf + 1, a, &na);   
  260.         }   
  261.         else convert(buf, a, &na);   
  262.         scanf("%s", buf);   
  263.         if (buf[0] == '-')   
  264.         {   
  265.             sign = !sign;   
  266.             convert(buf + 1, b, &nb);   
  267.         }   
  268.         else convert(buf, b, &nb);   
  269.         
  270.    
  271.           polynomial_multiply(a, na, b, nb, c, &nc);
  272.            t1 = 0;   
  273.             for (i = 0; i < nc; ++i)   
  274.             {   
  275.               t2 = t1 + c[i];   
  276.               c[i] = t2 % MOD;   
  277.               t1 = t2 / MOD;   
  278.             }   
  279.             for (; t1; t1 /= MOD) c[nc++] = t1 % MOD;   
  280.             if (sign) putchar('-');   
  281.             print(c, nc);
  282.         
  283.         printf("******************************************************\n");
  284.     }   
  285.     return 0;   
  286. }

  287.    
复制代码


@echo off
:re
cls
echo /*********************************************/
echo /     构建命令                                /
echo /*********************************************/
.\tools\x86\cl.exe .\src\hello_world.c /I".\inc\crt" /D"x86_xp" /I".\inc\api" /Fp:strict /Fa"Debug\hello_world.asm" /Fo"Debug\hello_world.obj" /c /MD

echo /*********************************************/
echo /                                             /
echo /*********************************************/


.\tools\x86\link.exe .\Debug\hello_world.obj /LIBPATH:".\lib\wxp\i386" /LIBPATH:".\lib\Crt\i386"  /OUT:"Debug\hello_world.exe" /NOLOGO /SUBSYSTEM:CONSOLE /MACHINE:X86 "kernel32.lib"
echo /*********************************************/
echo /                                             /
echo /*********************************************/


pause
goto re

本帖被以下淘专辑推荐:

回复

使用道具 举报

发表于 2016-7-29 17:21:35 | 显示全部楼层
咦,附件呢。。
回复

使用道具 举报

 楼主| 发表于 2016-7-29 19:52:57 | 显示全部楼层
...
_hello_world.7z.001.zip (1000 KB, 下载次数: 10)

_hello_world.7z.002.zip (1000 KB, 下载次数: 3)

_hello_world.7z.003.zip (1000 KB, 下载次数: 3)

_hello_world.7z.004.zip (909.34 KB, 下载次数: 3)

回复 赞! 靠!

使用道具 举报

发表于 2016-7-30 15:41:49 | 显示全部楼层
看样子我还得说明一下解压的办法,首先这后缀是zip但它不是zip压缩包,因此改后缀,去掉所有的“.zip”。
那么4个文件,应该是这样的文件名:
_hello_world.7z.001
_hello_world.7z.002
_hello_world.7z.003
_hello_world.7z.004
然后选中第一个文件,也就是_hello_world.7z.001,右键用7z打开就行了。
RAR能不能打开我还不知道。。但我还是自己上传一个单压缩文件免得有人不会解压。。。
_hello_world.7z (3.81 MB, 下载次数: 34)
回复 赞! 靠!

使用道具 举报

发表于 2016-8-25 13:53:00 | 显示全部楼层
請問一下,除了加上這些preprocessor之外,還需要加上甚麼嗎? compile之後出現error
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <complex.h>
回复 赞! 靠!

使用道具 举报

发表于 2016-11-17 10:31:59 | 显示全部楼层
支持    !!
回复 赞! 靠!

使用道具 举报

发表于 2016-11-17 10:32:20 | 显示全部楼层
支持    !!
回复 赞! 靠!

使用道具 举报

发表于 2016-11-17 10:32:45 | 显示全部楼层
支持    !!
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 06:58 , Processed in 0.036705 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表