Erhalten jeder einzelnen Ziffer aus einer ganzen Ganzzahl

Lesezeit: 7 Minuten

Benutzer-Avatar
Johannes Jensen

Nehmen wir an, ich habe eine Ganzzahl namens “score”, die so aussieht:

int score = 1529587;

Jetzt möchte ich jede Ziffer 1, 5, 2, 9, 5, 8, 7 aus der Partitur erhalten mit bitweisen Operatoren(Siehe unten Bearbeitungshinweis).

Ich bin mir ziemlich sicher, dass dies möglich ist, da ich einmal eine ähnliche Methode verwendet habe, um die roten, grünen und blauen Werte aus einem hexadezimalen Farbwert zu extrahieren.

Wie würde ich das tun?

Bearbeiten

Es müssen nicht unbedingt bitweise Operatoren sein, ich dachte nur, dass es so einfacher wäre.

  • Da ich es in meinem persönlichen Bitoperator-Kompendium nicht gefunden habe (graphics.stanford.edu/~seander/bithacks.html), glaube ich nicht, dass dies ohne eine tiefere Ausarbeitung möglich ist.

    – phimuemue

    25. Juni 2010 um 13:49 Uhr

  • Wenn sie dezimal sind, können Sie sie nicht bitweise abrufen. wenn sie hexadezimal sind, dann ist es möglich. bitte angeben.

    – Andrej

    25. Juni 2010 um 13:52 Uhr

Sie verwenden den Modulo-Operator:

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

Beachten Sie, dass Sie dadurch die Ziffern in umgekehrter Reihenfolge erhalten (dh die niedrigstwertige Ziffer zuerst). Wenn Sie die höchstwertige Ziffer zuerst wollen, müssen Sie die Ziffern in einem Array speichern und sie dann in umgekehrter Reihenfolge auslesen.

  • Ich bin mir ziemlich sicher, dass Modulo kein bitweiser Operator ist

    – Cyrill Gandon

    25. Juni 2010 um 13:48 Uhr

  • @Scorpi0: Nein, ist es nicht … aber es gibt keine vernünftige Möglichkeit, dies mit bitweisen Operatoren zu tun, und ich denke, das OP hat danach gesucht.

    –Martin B

    25. Juni 2010 um 13:49 Uhr

  • Ich denke, was OP hexadezimal bedeutete, und es ist möglich, es bitweise zu lösen.

    – Andrej

    25. Juni 2010 um 13:52 Uhr

  • @Andrey aus dem Beispiel ist klar, dass OP nach Dezimalziffern fragt.

    – Geoff

    25. Juni 2010 um 13:55 Uhr

  • Diese Lösung geht von einer Punktzahl >= 0 aus. Wenn score<0 dann wird diese Funktion niemals beendet.

    – Kuai

    1. Februar 2016 um 9:40 Uhr

RGB-Werte fallen gut auf Bitgrenzen; Dezimalziffern nicht. Ich glaube nicht, dass es eine einfache Möglichkeit gibt, dies mit bitweisen Operatoren zu tun. Sie müssten Dezimaloperatoren wie Modulo 10 (% 10) verwenden.

  • +1 Er hat recht, Dezimalzahlen (Basis 10) partitionieren nicht in Bits (Basis 2), außer bei Zahlen, die Potenzen von 2 sind (wie 256 = 2 ^ 8 für Farben). Da 10 keine Potenz von 2 ist, können Sie keine bitweisen Operatoren verwenden.

    – Geoff

    25. Juni 2010 um 13:49 Uhr


Stimme den vorherigen Antworten zu.

Eine kleine Korrektur: Es gibt einen besseren Weg, die Dezimalziffern von links nach rechts zu drucken, ohne zusätzlichen Puffer zuzuweisen. Außerdem möchten Sie möglicherweise ein Nullzeichen anzeigen, wenn die score ist 0 (die in den vorherigen Antworten vorgeschlagene Schleife druckt nichts).

Dies erfordert einen zusätzlichen Pass:

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

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

  • Diese Lösung bewirkt eine Division durch Null wenn score ist Null.

    – Schäfer

    8. Januar 2017 um 19:58 Uhr

  • Auch diese Lösung schlägt wegen Überlauf fehl, wenn der Score >= ceil (INT_MAX / 10.0) ist. Ich habe eine Lösung bereitgestellt, die Korrektur für den gesamten Bereich funktioniert [0, UINT_MAX].

    – Britton Krein

    14. Juni 2017 um 7:01 Uhr


  • Diese Lösung schlägt auch für jede Zahl mit 0-Ziffern an der niederwertigsten Position oder Positionen fehl. Diese Nullen werden nicht gedruckt. Die korrigierte Lösung, die ich bereitgestellt habe, vermeidet dieses Problem ebenfalls.

    – Britton Krein

    15. Juni 2017 um 20:08 Uhr

Benutzer-Avatar
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN

Erfinden Sie das Rad nicht neu. C hat sprintf aus einem Grund.

Da Ihre Variable Punktzahl heißt, schätze ich, dass dies für ein Spiel gilt, bei dem Sie die einzelnen Ziffern der Punktzahl verwenden möchten, um die numerischen Glyphen als Bilder anzuzeigen. In diesem Fall, sprintf verfügt über praktische Formatmodifikatoren, mit denen Sie die Partitur mit Nullen, Leerzeichen usw. auf eine feste Breite setzen können, die Sie möglicherweise verwenden möchten.

Benutzer-Avatar
Britton Krein

Diese Lösung liefert über den gesamten Bereich korrekte Ergebnisse [0,UINT_MAX]
ohne dass Ziffern gepuffert werden müssen.

Es funktioniert auch für breitere Typen oder vorzeichenbehaftete Typen (mit positiven Werten) mit entsprechenden Typänderungen.

Diese Art von Ansatz ist besonders nützlich in winzigen Umgebungen (z. B. Arduino-Bootloader), da es nicht dazu führt, dass das gesamte printf()-Bloat (wenn printf() nicht für die Demoausgabe verwendet wird) gezogen wird und sehr wenig RAM verwendet wird. Sie können den Wert sehen, indem Sie einfach eine einzelne LED blinken lassen 🙂

#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;
}

Benutzer-Avatar
PADYMKO

Normalerweise lässt sich dieses Problem lösen, indem das Modulo einer Zahl in einer Schleife verwendet oder eine Zahl in eine Zeichenfolge konvertiert wird. Um eine Zahl in eine Zeichenfolge umzuwandeln, können Sie die Funktion verwenden Itoabetrachtet also die Variante mit dem Modulo einer Zahl in einer Schleife.


Inhalt einer Datei 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);
}

Demo mit dem 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]

Demo mit 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]

Testumgebung

$~/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

Benutzer-Avatar
RohitK

#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);}

  • Hier ist eine modifizierte Version davon, die mit Null aufgefüllt wird uint64_t num = 5; uint64_t limit = 4; char * what[limit+1]; what[limit+1] = '\0'; uint64_t remainder = 0; uint64_t rev = 0; int count = 1; int digits = 0; while(num!=0) { remainder=num%10; rev=rev*10+remainder; num/=10; digits++; } if (remainder == 1 && digits != remainder) digits--; if (digits < limit) while(digits!=limit) { rev=rev*10; digits++; } while(rev!=0) { remainder=rev%10; what[count] = "0123456789"[remainder]; rev/=10; count++; }

    – PSP-CODER

    19. April 2020 um 9:27 Uhr


  • wobei if num ist 5 und Grenze ist 4 dann wird es produzieren 0005

    – PSP-CODER

    19. April 2020 um 9:30 Uhr


1383660cookie-checkErhalten jeder einzelnen Ziffer aus einer ganzen Ganzzahl

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy