问题分析:
我是在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!=0) ? -quo : quo; /* 获得最终结果 */
return (quo<-21474836478 || quo>2147483647) ? 2147483647 : quo; /* 结果溢出判断 */
}
时间复杂度:O(1)
空间复杂度:O(1)