这是描述:
给定两个整数除法和除数,在不使用乘法、除法和 mod 运算符的情况下除以两个整数。
除以除数后返回商。
整数除法应截断为零。除
- 数和除数都将是 32 位有符号整数。
- 除数永远不会为 0。
- 假设我们正在处理一个只能存储 32 位有符号整数范围内的整数的环境:[−2^31, 2^31 − 1]。出于此问题的目的,假设您的函数在除法结果溢出时返回 2^31 − 1。
我写了一个解决方案,但从第 s22 = s2 << curr;
行left shift of x by y places cannot be represented in type 'int'
,而我只使用无符号的短。我不知道为什么?
int divide(int dividend, int divisor) {
bool flag = false;
if (divisor == 0 || (dividend == INT_MIN && divisor == -1)) {
return INT_MAX;
}
unsigned short p1 = 0, p2 = 0, s1 = 0, s2 = 0;
if (divisor == INT_MIN) return 0;
if (dividend == INT_MIN) {
dividend = 0;
flag = !flag;
p1 = 0x8000;
p2 = 0x0;
}
if(dividend < 0) {
flag = !flag;
dividend = ~dividend + 1;
}
if(dividend != 0) {
p1 = dividend >> 16;
p2 = dividend & 0xffff;
}
if(divisor < 0) {
flag = !flag;
divisor = ~divisor + 1;
}
s1 = divisor >> 16;
s2 = divisor;
int ret = 0;
unsigned short curr = 31;
while(curr > -1) {
unsigned short p11 = p1 >> curr;
unsigned short p22, s11, s22;
s22 = s2 << curr;
if (curr > 15) {
p22 = p1 >> (curr - 16);
s11 = s2 << (curr - 16);
} else {
p22 = p2 >> curr | (p1 << (16 - curr));
s11 = (s1 << curr) | (s2 >> (16 - curr));
}
if (p11 > s1 || (p11 == s1 && p22 >= s2)) {
ret = (ret<<1) | 0x01;
if (p2 < s22) {
int tmp = p2 | 0x10000;
p2 = tmp - s22;
p1 = p1 - 1 - s11;
}
else {
p2 -= s22;
p1 -= s11;
}
}
else {
ret = ret << 1;
}
curr--;
}
return flag ? ~ret + 1 : ret;
}
我避免使用任何大于 int 的数据类型。
正如KamilCuk提到的,我不知道他为什么删除了评论。
左移有符号 int 是未定义的行为。并且移位无符号短 大于 16 也是未定义的,因为无符号短是 16 位。所以我必须处理这些边缘。
对于这个问题,我们有替代方法。 请通过
int dividend, divisor, quotient, reminder;
while(1)
{
printf("Enter no:n");
scanf("%d %d",÷nd,&divisor);
for(reminder = dividend, quotient = 0;divisor <= reminder;)
{
reminder = reminder - divisor;
quotient = quotient + 1;
}
printf("Quotien: %d Reminder: %d",quotient,reminder);
}