Как я могу посчитать цифры в целом числе без приведения строки? - PullRequest
33 голосов
/ 16 февраля 2009

Боюсь, на этот вопрос есть простой и очевидный ответ. Мне нужно определить, сколько цифр в ширину равно количеству элементов, чтобы я мог дополнить каждый номер элемента количеством минимум ведущих нулей, необходимых для поддержания выравнивания. Например, я не хочу, чтобы начальные нули, если сумма была <10, 1, если это от 10 до 99 и т. Д. </p>

Одним из решений было бы привести число элементов к строке, а затем считать символы. Тьфу! Есть ли лучший способ?

Редактировать: я бы не подумал использовать общий логарифм (я не знал, что такая вещь существует). Так что для меня это не очевидно, но определенно просто.

Ответы [ 10 ]

51 голосов
/ 16 февраля 2009

Это должно сделать это:

int length = (number ==0) ? 1 : (int)Math.log10(number) + 1;
12 голосов
/ 17 февраля 2009

Более эффективное решение, чем повторное деление, будет повторяться, если операторы с умножением ... например, (где n - номер, число цифр которого требуется)

unsigned int test = 1;
unsigned int digits = 0;
while (n >= test)
{
  ++digits;
  test *= 10;
}

Если есть некоторая разумная верхняя граница для количества элементов (например, 32-битный диапазон беззнакового целого), тогда еще лучший способ - сравнить с членами некоторого статического массива, например,

// this covers the whole range of 32-bit unsigned values
const unsigned int test[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };

unsigned int digits = 10;
while(n < test[digits]) --digits;
12 голосов
/ 17 февраля 2009
int length = (int)Math.Log10(Math.Abs(number)) + 1;

Возможно, вам придется учесть отрицательный знак ..

4 голосов
/ 17 февраля 2009

Если вы собираетесь дополнить номер в .Net, тогда

num.ToString().PadLeft(10, '0') 

может делать то, что вы хотите.

4 голосов
/ 16 февраля 2009

Вы можете использовать цикл while, который, вероятно, будет быстрее, чем логарифм, поскольку в нем используется только целочисленная арифметика:

int len = 0;
while (n > 0) {
    len++;
    n /= 10;
}

Я оставляю читателю в качестве упражнения настройку этого алгоритма для обработки нулевых и отрицательных чисел.

2 голосов
/ 17 февраля 2009

Я бы оставил комментарий, но мой рейтинг не даст мне этого различия.

Все, что я хотел отметить, это то, что хотя Log (10) является очень элегантным (читай: очень мало строк кода) решением, оно, вероятно, является наиболее сложным для процессора.

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

Особенно, если вы собираетесь делать это для большого количества цифр ..

1 голос
/ 17 февраля 2009

Поскольку у числа нет начальных нулей, вы все равно конвертируете, чтобы добавить их. Я не уверен, почему вы так стараетесь избежать того, чтобы найти длину, когда конечный результат все равно должен быть строкой.

0 голосов
/ 17 февраля 2009

Хорошо, я не могу устоять: используйте /=:

#include <stdio.h>

int
main(){
        int num = 423;
        int count = 1;
        while( num /= 10)
                count ++;
        printf("Count: %d\n", count);
        return 0;
}
534 $ gcc count.c && ./a.out
Count: 3
535 $ 
0 голосов
/ 16 февраля 2009

Вы можете выполнить цикл и удалить его на 10, сосчитать количество циклов;

int num = 423;
int minimum = 1;
while (num > 10) {
    num = num/10;
    minimum++;
}
0 голосов
/ 16 февраля 2009

Одно решение обеспечено логарифмом по основанию 10, немного излишним.

...