Проблема с использованием лимитов и очень больших чисел в C ++ - PullRequest
0 голосов
/ 14 апреля 2019

Это был третий или четвертый раз, когда я сталкивался с этой проблемой, и это только раздражает меня, потому что это не имеет смысла для меня как начинающего программиста.

Так что для моего класса я должен был создать программу (функцию внутри программы), которая будет находить наибольшую и наименьшую цифру в числе и возвращать число цифр в качестве переменной. Я ненавижу использовать ссылки, но сейчас это не главное.

Моя программа работает хорошо, как и ожидалось, ничего плохого не происходит, пока я не попытаюсь отправить наибольшее длинное длинное целое число в функцию.

Поскольку мне не нужно отрицательное число внутри моей функции, я использовал условие if, чтобы проверить, является ли число <0, и если это так, его нужно умножить на -1, чтобы получить положительное значение (я знаю, что мог бы использовать функция абс, но тот же результат). </p>

Когда я передаю наибольшее длинное длинное целое, которое равно -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 ]

1 голос
/ 14 апреля 2019

Представьте, что у вас есть 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 в 4 битах.В данном случае, Наибольшее отрицательное число не имеет соответствующего положительного значения, поэтому умножение на -1 переполняется и остается отрицательным. Переполнение фактически вызывает неопределенное поведение, что означает, что вам не нужно искать дальше.

0 голосов
/ 14 апреля 2019

Я думаю, что это может быть причиной. abs(min()) возвращает значение, которое на 1 больше max () определенного типа.

Для 32-битного целого, min() returns -2^31, while max returns 2^31 - 1 Для 64-битного long int

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

Так что, когда вы делаете n = n * -1, он не будет содержать это число, так как переполняется.

Таким образом, минимальное значение, которое вы можете проверить, это min () + 1

Кстати, так эффективнее делать

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