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

问题描述 投票:-1回答:2

这是遇到这个问题的第三次或第四次,它只是让我烦恼,因为这对我作为初学者程序员没有任何意义。

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

我的程序运行良好,正如预期的那样,在我尝试向函数发送最大的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;
}
c++ int limit long-integer
2个回答
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

现在你可以看到,你不能有一个正4位的正数。这就是这里的情况,The largest negative number does not have a corresponding positive value so the multiplication by -1 overflows and stays negative.溢出实际上会导致未定义的行为,这意味着你不需要再看了。


0
投票

我想这可能就是原因。 abs(min())返回的值比某个类型的max()大1。

对于32位int,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
© www.soinside.com 2019 - 2024. All rights reserved.