Получение каждой отдельной цифры из целого целого числа
Скажем, у меня есть целое число, называемое "оценка", которое выглядит так:
int score = 1529587;
Теперь то, что я хочу сделать, это получить каждую цифру 1, 5, 2, 9, 5, 8, 7 из оценки с помощью побитовых операторов (см. ниже заметку редактирования).
Я уверен, что это можно сделать, так как однажды я использовал аналогичный метод для извлечения красных зеленых и синих значений из шестнадцатеричного значения цвета.
Как мне это сделать?
Edit
Это не обязательно должно быть побитовым оператором, я просто подумал, что это будет проще.
Ответы
Ответ 1
Вы используете оператор modulo:
while(score)
{
printf("%d\n", score % 10);
score /= 10;
}
Обратите внимание, что это даст вам цифры в обратном порядке (то есть наименее значащие цифры). Если вы хотите сначала получить самую значительную цифру, вам нужно будет сохранить цифры в массиве, а затем прочитать их в обратном порядке.
Ответ 2
Согласитесь с предыдущими ответами.
Небольшая коррекция: лучший способ распечатать десятичные цифры слева направо, не выделяя дополнительный буфер. Кроме того, вы можете отображать нулевой символ, если score
равно 0 (цикл, предложенный в предыдущих ответах, не будет печатать anythng).
Для этого требуется дополнительный проход:
int div;
for (div = 1; div <= score; div *= 10)
;
do
{
div /= 10;
printf("%d\n", score / div);
score %= div;
} while (score);
Ответ 3
Значения RGB отлично падают на границах бит; десятичных цифр нет. Я не думаю, что есть простой способ сделать это, используя побитовые операторы вообще. Вам нужно будет использовать десятичные операторы, такие как modulo 10 (% 10).
Ответ 4
Не изобретайте велосипед. C имеет sprintf по какой-то причине. Поскольку ваша переменная называется счетом, я предполагаю, что это для игры, в которой вы планируете использовать отдельные цифры оценки, чтобы отображать цифры в виде изображений. В этом случае sprintf имеет удобные модификаторы формата, которые позволят вам использовать нуль-площадку, пробел и т.д. До фиксированной ширины, которую вы можете использовать.
Ответ 5
Это решение дает правильные результаты во всем диапазоне [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;
}
Ответ 6
Обычно эта проблема разрешается с использованием по модулю числа в цикле или преобразования числа в строку. Для преобразования числа в строку вы можете использовать функцию 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
Ответ 7
//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;
}
Ответ 8
#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);}