Значение делителя в цикле for таинственным образом (?) меняется

#java #for-loop #integer-division

#java #for-цикл #целочисленное деление

Вопрос:

Итак, я занимался этим часами, и, честно говоря, я полностью застрял. Я написал цикл for, который подсчитывает количество чисел в целом числе, но я обнаружил, что значение делителя меняется, как только я ввожу число выше 10 цифр, и я не могу понять, почему. Я безуспешно искал в Интернете, поэтому был бы признателен за любую помощь или советы, если они у вас есть. Спасибо!

  public static int getNumberOfDigits(long creditCardNumber)
{
    //problem with 0's at beginning and more than 10 digits
    int nDigitsInCard = 0;
    int divisor = (int) creditCardNumber;
    for(int i = 0; i <= creditCardNumber; i  ){
        while(divisor!=0){
            divisor/=10;
              nDigitsInCard;
        }
}
    // return the number of digits in nDigitsInCard

    return nDigitsInCard;
}
  

Комментарии:

1. измените int на long . Вы имеете дело со слишком большими числами для обработки примитива int. Что происходит, это повторный цикл (если диапазон был от — 10 до 10), затем ввод 11 приведет к повторному циклу до -10.

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

Ответ №1:

int s не может содержать числа, превышающие 2 147 483 647. Вам нужно придерживаться long s, чтобы работать с большими числами.

Комментарии:

1. К сожалению, после изменения типа данных на long в моем коде все еще возникает та же проблема.

2. @DarianRay Пожалуйста, обновите свой вопрос новым кодом.

3. Неважно, я понял это, я использовал неправильную переменную. Хотя тип данных long был частью этого. Спасибо за вашу помощь!

Ответ №2:

Целые числа могут содержать только числа до 2 ^ 32 — 1. Кроме того, почему вы преобразуете входной параметр в целое число?

Другое дело, что вы подсчитываете количество цифр в каждом числе, ведущем к делителю, поскольку вы выполняете цикл от 0 вплоть до creditCardNumber в for(int i = 0; i <= creditCardNumber; i ){ ... } . Так, например, 10000 вернет количество цифр в 1, количество цифр в 2, вплоть до 10000.

Наконец, вся функция может быть выполнена в одной строке с

 return Long.toString(creditCardNumber).length();
  

или

 return creditCardNumber.toString().length();
  

если вы измените creditCardNumber на Long вместо a long , но вам пришлось бы вызывать его с l суффиксом в конце.

Если вы хотите что-то еще более короткое, вы можете сделать

 return (creditCardNumber "").length();
  

Комментарии:

1. @ScaryWombat хорошая ошибка, исправлена

2. Привет! Спасибо за ввод, и с тех пор я исправил все эти ошибки. Я бы использовал . сокращение длины, если бы я мог, но мой профессор явно заявил, что этого не делать, поэтому я использовал цикл for.

Ответ №3:

Когда у вас есть число, превышающее 10 цифр, преобразование в целое число не завершается, потому что целое число не может содержать значения, превышающие 2 ^ 31 — 1, или 2,147,483,647, то есть число, состоящее всего из 10 цифр. Я рекомендую придерживаться long .