问题分析:
我是在Ubuntu Linux环境下开发C程序使用交叉编译器编译源码时遇见这个问题的。当时在给一款基于arm内核的处理器写驱动,使用了除法,遇到了这个问题。
出现这个问题的原因是arm内核不支持除法,arm没有实现除法的硬件,里面没有除法器(它应该是使用桶式移位寄存器实现的除法),当检测到代码使用了除法后,交叉编译器报错 undefined reference: __aeabi_idiv
解决方案:
解决方案有两种,一种是找到gcc除法库libgcc.a的位置,把它包含进程序,libgcc.a中有使用软件实现除法的程序;另一种就是自己写一个实现除法的函数,当用到除法时就调用这个函数,这里给出一个作者自己写的实现两个整型数据相除的程序
```C
int divide(int dividend, int divisor){ /* dividend: 被除数 divisor: 除数 返回商 */long long div=divisor, did=dividend; /* 除数,被除数 都转换为64位数据,避免溢出 */long long quo=0; /* 商 */int sign=0;/* 正负号处理,全部转换为无符号数进行移位运算 */if( did<0 ){ sign = !sign; did = -did; }if( div<0 ){ sign = !sign; div = -div; }/* 除法主体 */for( int i=31; (i>=0) ; i--){ /* 按移位次数从大到小试探 */ if( did>=(div<<i) ){ /* 最接近被除数且比被除数小的移位次数 */quo += ((long long)1<<i); /* 更新结果 */ //将计算出来的一个子项加到商上did -= (div<<i); /* 更新被除数 */ }}quo = (sign==1) ? -quo : quo; /* 获得最终结果 */return (quo<-21474836478 || quo>2147483647) ? 2147483647 : quo; /* 结果溢出判断 */
}?
时间复杂度:O(1)
空间复杂度:O(1)