Как получить N-ую цифру целого числа с побитовыми операциями? - PullRequest
31 голосов
/ 15 октября 2008

Пример. 123456, и мы хотим третий справа ('4').

Идея на практике состоит в том, чтобы получить доступ к каждой цифре отдельно (т.е. 6 5 4 3 2 1).

C / C ++ / C # предпочтительнее.

Ответы [ 12 ]

38 голосов
/ 15 октября 2008

Более эффективная реализация может выглядеть примерно так:

char nthdigit(int x, int n)
{
    while (n--) {
        x /= 10;
    }
    return (x % 10) + '0';
}

Это экономит усилия по преобразованию всех цифр в формат строки, если вам нужен только один из них. И вам не нужно выделять место для преобразованной строки.

Если скорость имеет значение, вы можете предварительно рассчитать массив степеней 10 и использовать n для индексации в этом массиве:

char nthdigit(int x, int n)
{
    static int powersof10[] = {1, 10, 100, 1000, ...};
    return ((x / powersof10[n]) % 10) + '0';
}

Как уже упоминалось другими, это настолько близко, насколько вы собираетесь перейти к побитовым операциям для базы 10.

5 голосов
/ 19 апреля 2013

Просто потратил время на написание этого, основываясь на ответах, поэтому подумал, что поделюсь.

Это основано на ответе Браннона, но позволяет вам получать более одной цифры за раз. В моем случае я использую его для извлечения деталей из даты и времени, сохраненных в int, где цифры представлены в формате ггггммдчннссм_s.

public static int GetDigits(this int number, int highestDigit, int numDigits)
{
    return (number / (int)Math.Pow(10, highestDigit - numDigits)) % (int)Math.Pow(10, numDigits);
}

Я сделал это расширением, вы, возможно, не захотите, но вот пример использования:

int i = 20010607;
string year = i.GetDigits(8,4).ToString();
string month = i.GetDigits(4,2).ToString();
string day = i.GetDigits(2,2).ToString();

Результаты:

год = 2001

месяц = ​​6

день = 7

5 голосов
/ 15 октября 2008

Использование математики по основанию-10:

class Program
{
    static void Main(string[] args)
    {
        int x = 123456;

        for (int i = 1; i <= 6; i++)
        {
            Console.WriteLine(GetDigit(x, i));
        }
    }

    static int GetDigit(int number, int digit)
    {
        return (number / (int)Math.Pow(10, digit - 1)) % 10;
    }
}

Производит:

6
5
4
3
2
1
3 голосов
/ 15 октября 2008

Причина, по которой он не будет работать (легко) с побитовыми операциями, заключается в том, что основание десятичной системы (10) не является степенью основания двоичной системы (2).

Если бы вы кодировали в базе 8, у вас было бы pow(2, 3) == 8, и вы могли бы извлечь каждую восьмеричную цифру как блок из трех битов.

Таким образом, вам действительно нужно преобразовать в базу 10, что обычно делается путем преобразования в строку (с помощью toString (Java) или sprintf (C), как другие показали в своих ответах).

2 голосов
/ 15 октября 2008

Это работает для неподписанных целых до 451069, как объяснено здесь :

def hundreds_digit(u): return mod10(div100(u))

def div100(u): return div10(div10(u))
def mod10(u):  return u - mul10(div10(u))
def mul10(u):  return ((u << 2) + u) << 1

def div10(u):
    Q = ((u >> 1) + u) >> 1  # Q = u*0.11
    Q = ((Q >> 4) + Q)       # Q = u*0.110011
    Q = ((Q >> 8) + Q) >> 3  # Q = u*0.00011001100110011
    return Q

# Alternatively:
#   def div100(u): return (u * 0xa3d7) >> 22
# though that'd only work for 16-bit u values.
# Or you could construct shifts and adds along the lines of div10(),
# but I didn't go to the trouble.

Тестирование:

>>> hundreds_digit(123456)
4
>>> hundreds_digit(123956)
9

Я был бы удивлен, если бы это было быстрее, хотя. Может быть, вам следует пересмотреть свою проблему.

1 голос
/ 02 ноября 2014

значение = (число% (позиция 10 ^)) / 10 ^ (позиция - 1)

Пример:

число = 23846

позиция = 1 -> значение = 6

position = 2 -> value = 4

position = 3 -> value = 8

Вот простой служебный метод Objective C, чтобы сделать это:

+ (int)digitAtPosition:(int)pos of:(int)number {

    return (number % ((int)pow(10, pos))) / (int)pow(10, pos - 1);
}
0 голосов
/ 04 марта 2018

будут пропущены две цифры d1 и d2. Программа должна напечатать nth Number - система счисления, состоящая только из цифр с d1 и d2 формат ввода первая строка содержит d1 вторая строка содержит d2 третьи корни содержат п d1 не равно d2

0 голосов
/ 11 июня 2016
int returndigit(int n,int d)
{
    d=d-1;
    while(d--)
    {
        n/=10;
    }
    return (n%10);
}
0 голосов
/ 05 декабря 2015

Просто для удовольствия, вот класс расширения C # для него:

public static class IntExtensions
{
    /// <summary>
    /// Returns the nth digit from an int, 
    /// where 0 is the least significant digit 
    /// and n is the most significant digit.
    /// </summary>
    public static int GetDigit(this int number, int digit)
    {
        for (int i = 0; i < digit; i++)
        {
            number /= 10;
        }
        return number % 10;
    }
}

Использование:

int myNumber = 12345;
int five = myNumber.GetDigit(0);
int four = myNumber.GetDigit(1);
int three = myNumber.GetDigit(2);
int two = myNumber.GetDigit(3);
int one = myNumber.GetDigit(4);
int zero = myNumber.GetDigit(5);
0 голосов
/ 08 июля 2015

Следующий код даст n-ю цифру справа в числе:

public void getDigit(long n,int k){
    int i=0;
    long r =0;
    while(i<n){
        r=n%10;
        n=n/10;
        i++;
    }
    System.out.println( k + "th digit from right " + r);
 }
...