[原创]10^9进制高精度大整数加法(MMX版本)
2004-07-13 12:17
453 查看
// 本代码使用在分治法的时候,不必考虑数据对齐的问题(如果考虑就复杂了),len也是偶数,所以后面的len为奇数的检查部分是没有必要的,跟一般的方法快不了多少,微乎其微,在此仅提供另外一种思路,本人原创的,如果你有更好的方法请告知// 实现 dest = a + b ,dest, a, b都是高位在前,低位在后,即dest[0]表示数的最高位,a,b也类似const unsigned int Base = 1000000000; // 10^9const unsigned __int64 Base64 = 0x3B9ACA003B9ACA00;const unsigned __int64 CarryFirst = 0x0000000100000000;const unsigned __int64 CarryNext = 0x0000000000000001;/* add_mmx() mmx指令版本 */__declspec(naked)long add_mmx(unsigned long *dest, unsigned long *a, unsigned long *b, size_t len){ __asm { mov ecx, dword ptr [esp+0x10] // len xor eax, eax test ecx, ecx jz add_exit push ebp mov ebp, ecx push ebx mov ebx, dword ptr [esp+0x14] // ebx = b push esi mov esi, dword ptr [esp+0x14] // esi = a push edi mov edi, dword ptr [esp+0x14] // edi = dest sub esi, ebx // esi = a - b lea edx, dword ptr [ebx+4*ecx-8] // &b[i] sub edi, ebx // edi = dest - b shr ecx, 1 // len = len / 2 movq mm7, Base64 // 0x3B9ACA003B9ACA00 movq mm5, CarryFirst // 0x0000000100000000 movq mm6, CarryNext // 0x0000000000000001 pxor mm2, mm2 // carry 清零add_loop: movq mm0, dword ptr [esi+edx] // a[i] movq mm1, dword ptr [edx] // b[i] paddd mm0, mm2 // sum = a[i]+carry movq mm3, mm7 // mm7 = Base64 paddd mm0, mm1 // sum += b[i] pcmpgtd mm3, mm0 // sum >= Base(10^9) ? 这里比较复杂,有讲究,必须比较2次 pandn mm3, mm5 // mm5 = CarryFirst psrlq mm3, 32 // 获得进位 CarryFirst, mm3 >> 32 movq mm4, mm7 // mm7 = Base64 paddd mm0, mm3 // 累加进位 pcmpgtd mm4, mm0 // sum >= Base(10^9) ? 进位以后,第二次比较 movq mm2, mm4 // 备份比较结果 pandn mm4, mm7 // 获得进位减法变量, 用于sum -= Base pandn mm2, mm6 // 获得下一次的进位, CarryNext psubd mm0, mm4 // 相当于 sum -= Base psllq mm2, 32 // carry = CarryNext << 32 movq dword ptr [edi+edx], mm0 // dest[i] = sum sub edx, 8 // edx = &b[i] - 8, 相当于i-=2 dec ecx // len-- jne add_loop test ebp, 1 // 如果len是奇数,则累加最后一个数 jz add_fast_ret mov ecx, dword ptr [esi+edx] // esi = a[i] mov ebx, dword ptr [edx] // edx = b[i] add ecx, ebx // sum = a[i] + b[i] mov ebx, Base // esi = Base add ecx, eax // sum += carry xor eax, eax // carry = 0 cmp ecx, ebx // sum >= Base ? jb add_sum // < mov eax, 1 // carry = 1 sub ecx, ebx // sum -= Baseadd_sum: mov dword ptr [edi+edx], ecx // dest[i] = sum pop edi pop esi pop ebx pop ebp emmsadd_exit: retadd_fast_ret: psrlq mm2, 32 // carry >> 32 movd eax, mm2 // 返回 carry pop edi pop esi pop ebx pop ebp emms ret }}
相关文章推荐
- [原创]10^9进制高精度大整数减法(MMX版本)
- 高精度整数(n进制,n<=10)加法
- c语言高精度大整数加法运算
- 任意长度的高精度大整数加法
- 2010年华为上机笔试二(高精度整数加法)
- 无线OSS-高精度整数加法(加数可以为负数,应实现高精度加减法)
- 高精度大整数加法
- 任意长度的高精度大整数加法
- 华为机试在线训练-牛客网(27)无线OSS-高精度整数加法
- 高精度 大整数加法
- 【华为机试】无线OSS-高精度整数加法
- 【vijos1033】【数值/数论】【高精度乘法】整数分解(版本2)
- 任意长度的高精度大整数和浮点数的加法和乘法
- 高精度整数加法(大整数加法)
- 高精度(大整数加法)
- 【华为OJ】【039-无线OSS-高精度整数加法】
- 华为OJ(高精度整数加法)
- 华为上机题:高精度整数加法
- OpenJudge百炼-2981-大整数加法-C语言-高精度计算
- 高精度整数加法