描述如下:
Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero.
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 2^31 − 1 when the division result overflows.
我写了一个解决方案,但得到了 left shift of x by y places cannot be represented in type 'int'
来自线 s22 = s2 << curr;
而我只使用无符号短。不知道为什么?
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 提到的,我不知道他为什么删除该评论。
左移有符号整数是未定义的行为。并且将 unsignedshort 移位超过 16 也是未定义的,因为 unsignedshort 是 16 位。所以我必须处理这些边缘。
关于c - 除两个整数 [leetcode] 使用 unsigned Short 时发生移位错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55587802/