在C ++中使用限制和非常大的数字的问题

时间:2019-04-14 17:31:39

标签: c++ int limit long-integer

这是第三次或第四次遇到此问题,这让我很烦,因为对于初学者来说这对我来说毫无意义。

因此,对于我的班级,我必须制作一个程序(程序中的函数),该程序将找到数字中的最大和最小数字,并将数字计数返回为变量。我讨厌使用引用,但是那不是现在的重点。

我的程序运行良好,可以预期的是,直到尝试将最大的long long int数发送给函数之前,一切都没有发生。

因为我的函数中不需要负数,所以我使用了if语句来检查数字是否为<0,如果是,则应将其乘以-1以获得正数(我知道我可以使用abs函数,但结果相同)。

当我传递最大的long long int值时,即−9,223,372,036,854,775,807程序返回该数字小于0,但还返回一个负数,而不是一个正数,但是当我测试−9,223,372,036,854,775,807时,该数字为-1再次工作。

所以我的问题是这里实际上发生了什么,为什么n * =-1部分被忽略,是因为数字正在使用所有内存还是?

int Digits(long long int n,int &c_min,int &c_max){

    c_min=9;
    c_max=0;

    if(n<0){
        n*=-1;
    }

    int digit;
    int numberOfDigits(0);

    while(n!=0){
        digit=n%10;
        if(digit > c_max) c_max=digit;
        if(digit< c_min) c_min=digit;
        numberOfDigits++;
        n/=10;
    }



    if(numberOfDigits==0){
        c_min=0;
        c_max=0;
        return 1;
    }

    return numberOfDigits;
}

主要功能:

int main ()
{
    int mini,maxi;
    int e = Digits(std::numeric_limits<long long int>::min(), mini, maxi);

    std::cout << e;

    return 0;
}

2 个答案:

答案 0 :(得分:1)

想象一下,您的数字有4位,这意味着您可以存储2 ^ 4个数字,即16。现在,由于您需要正数和负数,因此您可能希望将其分成两半并得到8个正数, 8个负数。但是您还需要零,这意味着除零外,您还有15个数字。发生的情况是您有从-8到正7的数字,也就是16个数字:

-8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7

现在您可以看到,四位中的正数不能为8。这里就是这种情况,The largest negative number does not have a corresponding positive value so the multiplication by -1 overflows and stays negative.溢出实际上会导致未定义的行为,这意味着您无需再进行检查。

答案 1 :(得分:0)

我认为这可能是原因。 abs(min())返回的值比某种类型的max()大1。

对于32位整数,min() returns -2^31, while max returns 2^31 - 1 对于长64位的int,

min() returns -2^63 while max() returns 2^63 - 1

因此,当您执行n = n * -1时,由于溢出该数字将不保存该数字。

所以您可以测试的最小值为min()+ 1

顺便说一句,这样做的效率更高

n = -n
instead of 
n = n * -1