Способ получить количество цифр в INT? - PullRequest
353 голосов
/ 20 августа 2009

Есть ли более точный способ получения длины типа int, чем этот метод?

int length = String.valueOf(1000).length();

Ответы [ 27 ]

0 голосов
/ 10 июня 2015

Я еще не видел решения на основе умножения. Решения, основанные на логарифме, делении и строках, станут довольно громоздкими для миллионов тестовых случаев, поэтому вот один для ints:

/**
 * Returns the number of digits needed to represents an {@code int} value in 
 * the given radix, disregarding any sign.
 */
public static int len(int n, int radix) {
    radixCheck(radix); 
    // if you want to establish some limitation other than radix > 2
    n = Math.abs(n);

    int len = 1;
    long min = radix - 1;

    while (n > min) {
        n -= min;
        min *= radix;
        len++;
    }

    return len;
}

В базе 10 это работает, потому что n по существу сравнивается с 9, 99, 999 ... как минимум 9, 90, 900 ... и n вычитается из 9, 90, 900 ...

К сожалению, это не переносится на long, просто заменяя каждый экземпляр int из-за переполнения. С другой стороны, так уж получилось, что будет работать для баз 2 и 10 (но плохо для большинства других баз). Вам понадобится таблица соответствия для точек переполнения (или теста деления ... ew)

/**
 * For radices 2 &le r &le Character.MAX_VALUE (36)
 */
private static long[] overflowpt = {-1, -1, 4611686018427387904L,
    8105110306037952534L, 3458764513820540928L, 5960464477539062500L,
    3948651115268014080L, 3351275184499704042L, 8070450532247928832L,
    1200757082375992968L, 9000000000000000000L, 5054470284992937710L,
    2033726847845400576L, 7984999310198158092L, 2022385242251558912L,
    6130514465332031250L, 1080863910568919040L, 2694045224950414864L,
    6371827248895377408L, 756953702320627062L, 1556480000000000000L,
    3089447554782389220L, 5939011215544737792L, 482121737504447062L,
    839967991029301248L, 1430511474609375000L, 2385723916542054400L,
    3902460517721977146L, 6269893157408735232L, 341614273439763212L,
    513726300000000000L, 762254306892144930L, 1116892707587883008L,
    1617347408439258144L, 2316231840055068672L, 3282671350683593750L,
    4606759634479349760L};

public static int len(long n, int radix) {
    radixCheck(radix);
    n = abs(n);

    int len = 1;
    long min = radix - 1;
    while (n > min) {
        len++;
        if (min == overflowpt[radix]) break;
        n -= min;
        min *= radix;

    }

    return len;
}
0 голосов
/ 09 июня 2015

Или вместо длины вы можете проверить, больше или меньше число, чем желаемое число.

    public void createCard(int cardNumber, int cardStatus, int customerId) throws SQLException {
    if(cardDao.checkIfCardExists(cardNumber) == false) {
        if(cardDao.createCard(cardNumber, cardStatus, customerId) == true) {
            System.out.println("Card created successfully");
        } else {

        }
    } else {
        System.out.println("Card already exists, try with another Card Number");
        do {
            System.out.println("Enter your new Card Number: ");
            scan = new Scanner(System.in);
            int inputCardNumber = scan.nextInt();
            cardNumber = inputCardNumber;
        } while(cardNumber < 95000000);
        cardDao.createCard(cardNumber, cardStatus, customerId);
    }
}

}

0 голосов
/ 17 декабря 2014

С дизайном (на основе проблемы). Это альтернатива разделяй и властвуй. Сначала мы определим enum (учитывая, что это только для беззнакового целого).

public enum IntegerLength {
    One((byte)1,10),
    Two((byte)2,100),
    Three((byte)3,1000),
    Four((byte)4,10000),
    Five((byte)5,100000),
    Six((byte)6,1000000),
    Seven((byte)7,10000000),
    Eight((byte)8,100000000),
    Nine((byte)9,1000000000);

    byte length;
    int value;

    IntegerLength(byte len,int value) {
        this.length = len;
        this.value = value;
    }

    public byte getLenght() {
        return length;
    }

    public int getValue() {
        return value;
    }
}

Теперь мы определим класс, который проходит через значения перечисления, сравнивает и возвращает соответствующую длину.

public class IntegerLenght {
    public static byte calculateIntLenght(int num) {    
        for(IntegerLength v : IntegerLength.values()) {
            if(num < v.getValue()){
                return v.getLenght();
            }
        }
        return 0;
    }
}

Время выполнения этого решения такое же, как и в подходе «разделяй и властвуй».

0 голосов
/ 10 ноября 2014
    int num = 02300;
    int count = 0;
    while(num>0){
         if(num == 0) break;
         num=num/10;
         count++;
    }
    System.out.println(count);
0 голосов
/ 24 августа 2014

Действительно простое решение:

public int numLength(int n) {
  for (int length = 1; n % Math.pow(10, length) != n; length++) {}
  return length;
}
0 голосов
/ 30 марта 2013

простое решение:

public class long_length {
    long x,l=1,n;
    for (n=10;n<x;n*=10){
        if (x/n!=0){
            l++;
        }
    }
    System.out.print(l);
}
0 голосов
/ 21 апреля 2013

Вот очень простой метод, который я сделал, который работает для любого числа:

public static int numberLength(int userNumber) {

    int numberCounter = 10;
    boolean condition = true;
    int digitLength = 1;

    while (condition) {
        int numberRatio = userNumber / numberCounter;
        if (numberRatio < 1) {
            condition = false;
        } else {
            digitLength++;
            numberCounter *= 10;
        }
    }

    return digitLength; 
}

Способ работы с переменной счетчика чисел состоит в том, что 10 = 1 разряд. Например .1 = 1 десятая => 1 разрядный пробел. Поэтому, если у вас int number = 103342;, вы получите 6, потому что это эквивалентно .000001 пробелов назад. Кроме того, у кого-нибудь есть лучшее имя переменной для numberCounter? Я не могу придумать ничего лучшего.

Редактировать: Просто подумал о лучшем объяснении. По сути, этот цикл while делает так, что вы делите свое число на 10, пока оно не станет меньше единицы. По сути, когда вы делите что-то на 10, вы перемещаете его назад на один номер, поэтому вы просто делите это на 10, пока не достигнете <1 для количества цифр в вашем номере. </p>

Вот еще одна версия, которая может считать количество чисел в десятичном виде:

public static int repeatingLength(double decimalNumber) {

    int numberCounter = 1;
    boolean condition = true;
    int digitLength = 1;

    while (condition) {
        double numberRatio = decimalNumber * numberCounter;

        if ((numberRatio - Math.round(numberRatio)) < 0.0000001) {
            condition = false;
        } else {
            digitLength++;
            numberCounter *= 10;
        }
    }
    return digitLength - 1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...