Как я могу посчитать цифры в целом числе без преобразования строки?

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

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

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

10 ответов

Решение

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

int length = (number ==0) ? 1 : (int)Math.log10(number) + 1;
int length = (int)Math.Log10(Math.Abs(number)) + 1;

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

Более эффективное решение, чем повторное деление, будет повторяться, если операторы с умножением... например (где 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;

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

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

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

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

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

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

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

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

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

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

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

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

Хорошо, я не могу устоять /=:

#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 $ 

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

int num = 423;
int minimum = 1;
while (num > 10) {
    num = num/10;
    minimum++;
}
Другие вопросы по тегам