- 论坛徽章:
- 15
|
本帖最后由 yulihua49 于 2010-11-26 15:15 编辑
回复 juffun
举个例子吧:二进制字符串为1111
首先要知道一个常识:(a+b)%c=(a%c+b%c)%c;
...
ecjtubaowp 发表于 2010-11-26 11:05 ![]()
m*2 改 m<<1,效率可提高。你这是二进制啊,太费力了。
我上边的例子用了div1,多位数除以1位数的除法,一次处理32bit效率似乎好些。- int div1(n,pa,b,pq)
- u_int n,*pa,b,*pq;
- {
- int rem[2];
- if(b<2) {
- if(b==1) numcpy(n,pq,pa);
- else n_zero(n,pq);
- return 0;
- }
- rem[0]=rem[1]=0;
- do {
- n--;
- rem[0]=pa[n];
- rem[1]=diva(rem,b,pq+n);
- } while(n);
- return rem[1];
- }
复制代码 里边用到单除法,在intel机器上,可以用asm做,一条指令得到余数和商,效率较高:64位汇编哦!- .file "diva.c"
- .text
- .p2align 4,,15
- /*
- unsigned long diva(unsigned long a[2],unsigned long c,unsigned long *rem);
- */
- .globl diva
- .type diva, @function
- diva64:
- .LFB2:
- movq (%rdi), %rax
- movq %rdx, %r8
- movq 8(%rdi), %rdx
- divq %rsi
- movq %rdx, (%r8)
- ret
- .LFE2:
- .size diva, .-diva
- .section .eh_frame,"a",@progbits
- .Lframe1:
- .long .LECIE1-.LSCIE1
- .LSCIE1:
- .long 0x0
- .byte 0x1
- .string "zR"
- .uleb128 0x1
- .sleb128 -8
- .byte 0x10
- .uleb128 0x1
- .byte 0x3
- .byte 0xc
- .uleb128 0x7
- .uleb128 0x8
- .byte 0x90
- .uleb128 0x1
- .align 8
- .LECIE1:
- .LSFDE1:
- .long .LEFDE1-.LASFDE1
- .LASFDE1:
- .long .LASFDE1-.Lframe1
- .long .LFB2
- .long .LFE2-.LFB2
- .uleb128 0x0
- .align 8
- .LEFDE1:
- .ident "GCC: (GNU) 4.1.2 20070115 (prerelease) (SUSE Linux)"
- .section .note.GNU-stack,"",@progbits
复制代码 如果想可移植,可以用这个,效率稍差:- int diva(pa,b,pq)
- u_int *pa,b,*pq;
- {
- unsigned long long tp,d,q;
- tp=((long long)pa[1])<<32;
- tp += 0XFFFFFFFF & pa[0];
- d=b;
- q=tp/d;
- *pq=q&0xFFFFFFFF;
- q=tp%d;
- return (u_int)q;
- }
复制代码 |
|