在C++程序中使用abs()超过时间限制

Time Limit Exceeded with abs() in a C++ Program

本文关键字:过时 时间 abs 程序 C++      更新时间:2023-10-16

我在一个程序中遇到了abs()的问题。当我使用代码时:

long long dvd = abs(dividend), dvs = abs(divisor);

据报道"超过时限"

使用时:

long long dvd = dividend, dvs = divisor;
dvd = abs(dvd);
dvs = abs(dvs);

一切都很好。。。

完整代码如下:

class Solution {
public:
    int divide(int dividend, int divisor) {
    long long dvd = dividend, dvs = divisor;
    dvd = abs(dvd);
    dvs = abs(dvs);
    long long result = 0;
    while (dvd >= dvs) {
        long long temp = dvs;
        int i = 0;
        while (dvd >= temp) {
            temp = temp << 1;
            i++;
        }
        dvd -= dvs << (i-1);
        result += (long long)1 << (i-1);
    }
    result = ((long long)dividend > 0 ^ (long long)divisor > 0) ? -result : result;
    if (result > (1<<31) - 1)
        return (1<<31) - 1;
    return result;
  }
};

有人能在这里解释一下abs()发生了什么吗?

abs()很可能是一个定义如下的宏:

#define abs(x) (((x)<0)?-(x):(x))

或类似定义的模板:

template <typename T>
T abs (T x) { return (x < 0) ? -x : x; }

因此,abs()的结果值采用与其参数相同的类型。对于int类型的参数,abs(INT_MIN)可能定义得很好,也可能定义得不好,因为它可能会导致有符号整数溢出。(从技术上讲,有符号整数溢出会调用未定义的行为。)然而,在2s补码系统上,它可能会产生INT_MIN本身。


对于以下情况(给出时限错误的情况):

int divide(int dividend, int divisor) {
    long long dvd = abs(dividend), dvs = abs(divisor);

如果divisorINT_MIN,那么dvs很可能是INT_MIN。因此,它是负面的。

现在,稍后,您将获得:

        long long temp = dvs;
        int i = 0;
        while (dvd >= temp) {
            temp = temp << 1;
            i++;
        }

如果dvd是非负的,这是一个无限循环。这是因为CCD_ 12变为CCD_。


你的"固定"版本之所以有效,是因为这里:

int divide(int dividend, int divisor) {
    long long dvd = dividend, dvs = divisor;
    dvd = abs(dvd);
    dvs = abs(dvs);

您已将参数的类型更改为abs(),使其成为long long,并由int初始化。因此,如果dvs(long long)INT_MIN,则abs(dvs)-(long long)INT_MIN,只要是sizeof(int) < sizeof(long long)的正数。