/*文件名称:DIV64_32.C制作日期: 2008.8.15 REV2作者: zzwj5120Email: wjandcf@gmail.com zzwj5120@sina.com源程序: 64位无符号二进制整数除法原理(C语言描述)函数功能: 64位无符号二进制整数除以32位无符号二进制整数 0000 0001 0000 0000 -----------------------------------------0000 0000 ffff ffff ) 0000 0000 0000 0000 ffff ffff 0000 0000 0000 0000 ffff ffff ----------------------------------------- 0 */typedef signed short int16; /* defined for nsigned 16-bits integer variable 有符号16位整型变量 */typedef signed int int32; /* defined for nsigned 32-bits integer variable 有符号32位整型变量 */typedef long long int64; /* defined for nsigned 64-bits integer variable 有符号64位整型变量 */typedef unsigned short uint16; /* defined for unsigned 16-bits integer variable 无符号16位整型变量 */typedef unsigned int uint32; /* defined for unsigned 32-bits integer variable 无符号32位整型变量 */typedef unsigned long long uint64; /* defined for unsigned 64-bits integer variable 无符号64位整型变量 *//*入口参数: ll, 被除数 bb, 除数 addr3 商指针 addr4, 余数指针返回参数: 返回1表示除数为0, 返回0表示正常*/ uint16 uint64_div_uint32(uint64 ll, uint32 bb, uint64 * addr3, uint32 * addr4){ union { uint64 un[2]; //64位被除数扩展为128位,高64位为被除数左移64次而设 struct{ uint32 l0; //0 uint32 h0; //1 uint32 l1; //2 uint32 h1; //3 }st; }aa; uint64 cc; //64位商 register uint32 i; if(bb == 0)return 1; //除数为0返回1 if(ll < bb){ *addr3 = 0; //商 *addr4 = ll; //余数 return 0; //被除数小于除数,商为0,余数即被除数 } aa.un[0] = ll; //被除数 64bit aa.un[1] = 0; //扩展到128bit cc = 0; //商 64bit 清0 i = 0; //第一步优化, 被除数为32位, 直接更改左移循环次数 if(aa.st.h0 == 0){ aa.st.h0 = aa.st.l0; aa.st.l0 = 0; i = 32; } //第二步优化, 左移直到被除数首位为1 for(;i<64; ++i){ if((aa.st.h0&0x80000000)==0x80000000)break; else aa.un[0] = aa.un[0] << 1; } //被除数左移, 和除数比较, 获取商位和余数 for (; i<64; ++i){ aa.un[1] = (aa.un[1] << 1) + (aa.un[0] >> 63); aa.un[0] = aa.un[0] << 1; //被除数左移1位 cc = cc << 1 ; //商左移1位 if(aa.un[1] >= bb){ //如果除数为32位,只可以用33位和除数比较 aa.un[1] = aa.un[1]- bb; //32位被除数可能比除数小,但有进位33 ++cc; } } *addr3 = cc; //商 *addr4 = aa.st.l1; //余数 return 0; }/* 一个不懂汇编的程序员,可能是一个合格的程序员但一定不是一个完美的程序员。进一步的优化, 是根据不同处理器, 将C函数转为具体汇编指令。 */
联系客服