Как получить N-ю цифру целого числа с битовыми операциями?
Пример. 123456, и мы хотим, чтобы третий справа ('4') вышел.
Идея на практике заключается в доступе к каждой цифре отдельно (т.е. 6 5 4 3 2 1).
C/С++/С#.
Ответы
Ответ 1
Более эффективная реализация может быть примерно такой:
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.
Ответ 2
Просто потратил время, написав это на основе ответов здесь, так что думал, что буду делиться.
Это основано на ответе Браннона, но позволяет вам получать более одной цифры за раз. В моем случае я использую его для извлечения деталей из даты и времени, сохраненных в int, где цифры находятся в формате yyyymmddhhnnssm_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
month = 6
день = 7
Ответ 3
Используйте математику base-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
Ответ 4
Причина, по которой он не будет работать (с легкостью) с побитовыми операциями, заключается в том, что база десятичной системы (10) не является основанием базы двоичной системы (2).
Если вы кодировали в базе 8, у вас был бы pow(2, 3) == 8
и мог бы извлечь каждую восьмеричную цифру в виде блока из трех бит.
Итак, вам действительно нужно преобразовать в base 10, что обычно делается путем преобразования в строку (с помощью toString (Java) или sprintf (C), как показали другие в своих ответах).
Ответ 5
Это работает для unsigned ints до 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
Я был бы удивлен, если бы это было быстрее. Возможно, вам стоит пересмотреть свою проблему.
Ответ 6
value = (число% (позиция 10))/10 ^ (позиция - 1)
Пример:
number = 23846
position = 1 → value = 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);
}
Ответ 7
Вы можете попробовать побитовый сдвиг-левый (для N-1), а затем прочитать цифру в [0], поскольку это может быть ассемблерный подход.
123456 → 456 → читать первую цифру
Ответ 8
Следующий код даст 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);
}
Ответ 9
Просто для удовольствия, вот для него класс расширения С#:
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);
Ответ 10
int returndigit(int n,int d)
{
d=d-1;
while(d--)
{
n/=10;
}
return (n%10);
}
Ответ 11
В C вы можете сделать что-то вроде следующего, где n = 0 указывает самую правую цифру
char nthDigitFromRight(int x,int n)
{
char str[20];
sprintf(str,"%020d",x);
return(str[19 - x]);
}
Измените [19-x] на [20-x], если вы хотите n = 1 для самой правой цифры.