Получение каждой отдельной цифры из целого числа - PullRequest
21 голосов
/ 25 июня 2010

Допустим, у меня есть целое число, называемое «счет», которое выглядит так:

int score = 1529587;

Теперь я хочу получить каждую цифру 1, 5, 2, 9, 5, 8, 7 из партитуры , используя побитовые операторы (см. Примечание для редактирования ниже).

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

Как бы я это сделал?

Редактировать
Это не обязательно должны быть побитовые операторы, я просто подумал, что так будет проще.

Ответы [ 8 ]

40 голосов
/ 25 июня 2010

Вы используете оператор по модулю:

while(score)
{
    printf("%d\n", score % 10);
    score /= 10;
}

Обратите внимание, что это даст вам цифры в обратном порядке (т.е. сначала младшая цифра).Если вы хотите сначала получить наиболее значимую цифру, вам нужно сохранить цифры в массиве, а затем прочитать их в обратном порядке.

5 голосов
/ 25 июня 2010

Согласен с предыдущими ответами.

Небольшое исправление: есть лучший способ печатать десятичные цифры слева направо, без выделения дополнительного буфера. Кроме того, вы можете захотеть отобразить нулевой символ, если score равно 0 (цикл, предложенный в предыдущих ответах, не будет печататься)

Это требует дополнительного прохода:

int div;
for (div = 1; div <= score; div *= 10)
    ;

do
{
    div /= 10;
    printf("%d\n", score / div);
    score %= div;
} while (score);
4 голосов
/ 25 июня 2010

Значения RGB хорошо ложатся на границы битов;десятичных цифр нет.Я не думаю, что есть простой способ сделать это с помощью побитовых операторов вообще.Вам нужно будет использовать десятичные операторы, такие как модуль 10 (% 10).

2 голосов
/ 26 июня 2010

Не изобретай велосипед. У Спринта есть причина. Поскольку ваша переменная называется Score, я предполагаю, что это для игры, в которой вы планируете использовать отдельные цифры счета для отображения цифровых символов в виде изображений. В этом случае sprintf имеет удобные модификаторы формата, которые позволят вам добавлять ноль, пробел и т. Д. К фиксированной ширине, которую вы можете использовать.

1 голос
/ 14 июня 2017

Это решение дает правильные результаты во всем диапазоне [0, UINT_MAX] без необходимости буферизации цифр.

Он также работает для более широких типов или типов со знаком (с положительными значениями) с соответствующими изменениями типов.

Этот подход особенно полезен в крошечных средах (например, загрузчик Arduino), потому что он не 'В конечном итоге тянет за собой весь метод printf () (когда printf () не используется для демонстрационного вывода) и использует очень мало оперативной памяти.Вы можете посмотреть на значение, просто мигнув одним светодиодом:)

#include <limits.h>
#include <stdio.h>

int
main (void)
{
  unsigned int score = 42;   // Works for score in [0, UINT_MAX]

  printf ("score via printf:     %u\n", score);   // For validation

  printf ("score digit by digit: ");
  unsigned int div = 1;
  unsigned int digit_count = 1;
  while ( div <= score / 10 ) {
    digit_count++;
    div *= 10;
  }
  while ( digit_count > 0 ) {
    printf ("%d", score / div);
    score %= div;
    div /= 10;
    digit_count--;
  }
  printf ("\n");

  return 0;
}
0 голосов
/ 04 сентября 2018
#include<stdio.h>

int main() {
int num; //given integer
int reminder;
int rev=0; //To reverse the given integer
int count=1;

printf("Enter the integer:");
scanf("%i",&num);

/*First while loop will reverse the number*/
while(num!=0)
{
    reminder=num%10;
    rev=rev*10+reminder;
    num/=10;
}
/*Second while loop will give the number from left to right*/
while(rev!=0)
{
    reminder=rev%10;
    printf("The %d digit is %d\n",count, reminder);
    rev/=10;
    count++; //to give the number from left to right 
}
return (EXIT_SUCCESS);}
0 голосов
/ 19 июля 2018
//this can be easily understandable for beginners     
int score=12344534;
int div;
for (div = 1; div <= score; div *= 10)
{

}
/*for (div = 1; div <= score; div *= 10); for loop with semicolon or empty body is same*/
while(score>0)
{
    div /= 10;
    printf("%d\n`enter code here`", score / div);
    score %= div;
}
0 голосов
/ 11 марта 2017

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


Содержимое файла get_digits.c

$ cat get_digits.c 

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


// return a length of integer
unsigned long int get_number_count_digits(long int number);

// get digits from an integer number into an array
int number_get_digits(long int number, int **digits, unsigned int *len);

// for demo features
void demo_number_get_digits(long int number);


int
main()
{
    demo_number_get_digits(-9999999999999);
    demo_number_get_digits(-10000000000);
    demo_number_get_digits(-1000);
    demo_number_get_digits(-9);
    demo_number_get_digits(0);
    demo_number_get_digits(9);
    demo_number_get_digits(1000);
    demo_number_get_digits(10000000000);
    demo_number_get_digits(9999999999999);
    return EXIT_SUCCESS;
}


unsigned long int
get_number_count_digits(long int number)
{
    if (number < 0)
        number = llabs(number);
    else if (number == 0)
        return 1;

    if (number < 999999999999997)
        return floor(log10(number)) + 1;

    unsigned long int count = 0;
    while (number > 0) {
        ++count;
        number /= 10;
    }
    return count;
}


int
number_get_digits(long int number, int **digits, unsigned int *len)
{
    number = labs(number);

    // termination count digits and size of a array as well as
    *len = get_number_count_digits(number);

    *digits = realloc(*digits, *len * sizeof(int));

    // fill up the array
    unsigned int index = 0;
    while (number > 0) {
        (*digits)[index] = (int)(number % 10);
        number /= 10;
        ++index;
    }

    // reverse the array
    unsigned long int i = 0, half_len = (*len / 2);
    int swap;
    while (i < half_len) {
        swap = (*digits)[i];
        (*digits)[i] = (*digits)[*len - i - 1];
        (*digits)[*len - i - 1] = swap;
         ++i;
    }

    return 0;
}


void
demo_number_get_digits(long int number)
{
    int *digits;
    unsigned int len;

    digits = malloc(sizeof(int));

    number_get_digits(number, &digits, &len);

    printf("%ld --> [", number);
    for (unsigned int i = 0; i < len; ++i) {
        if (i == len - 1)
            printf("%d", digits[i]);
        else
            printf("%d, ", digits[i]);
    }
    printf("]\n");

    free(digits);
}

Демонстрация с GNU GCC

$~/Downloads/temp$ cc -Wall -Wextra -std=c11 -o run get_digits.c -lm
$~/Downloads/temp$ ./run
-9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
-10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-1000 --> [1, 0, 0, 0]
-9 --> [9]
0 --> [0]
9 --> [9]
1000 --> [1, 0, 0, 0]
10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

Демонстрация с LLVM / Clang

$~/Downloads/temp$ rm run
$~/Downloads/temp$ clang -std=c11 -Wall -Wextra get_digits.c -o run -lm
setivolkylany$~/Downloads/temp$ ./run
-9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
-10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-1000 --> [1, 0, 0, 0]
-9 --> [9]
0 --> [0]
9 --> [9]
1000 --> [1, 0, 0, 0]
10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

Тестированиеокружающая среда

$~/Downloads/temp$ cc --version | head -n 1
cc (Debian 4.9.2-10) 4.9.2
$~/Downloads/temp$ clang --version
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
...