Ganzzahlen >9999 in PIC C18

In dieser Antwort habe ich eine Funktion erstellt, um eine Ganzzahl in eine ASCII-Zeichenfolge zu konvertieren:

void writeInteger(unsigned int input) {
    unsigned int start = 1;
    unsigned int counter;
    while (start <= input)
        start *= 10;
    for (counter = start / 10; counter >= 1; counter /= 10)
        serialWrite(((input / counter) % 10) + 0x30);
}

Ich habe diese Funktion mit einer Schleife getestet:

unsigned int counter;
for (counter = 0; counter< 1000000; counter++) {
    writeInteger(counter);
    serialWrite('\r');
    serialWrite('\n');
}

Das funktioniert z 1 N 9999 . Bei 10.000 und mehr erhalte ich jedoch seltsame Zeichenfolgen auf dem Terminal:

10000 => 2943
10001 => 2943
10002 => 2944
10003 => 2944
10004 => 2944
10005 => 2945
...

Warum das? Wie kann ich es reparieren?

Überprüfen Sie diese Antwort: stackoverflow.com/questions/6302195/… Sie möchten Ihre Divisionen wirklich auf das Minimum beschränken, da sie langsam sind
counter<1,000,0000Sie haben im Wesentlichen gemacht . Zähler ist jedoch einint
@abdullahkahraman ja, danke - ich dachte, ein intwürde 32 Bit halten, wie zum Beispiel in Java.
Hier ist meine Routine, die für einen 8-Bit-Mikrocontroller optimiert ist. Es ist schnell, da es keinen Modulus oder keine Multiplikation verwendet. Sie können es auch leicht ändern, sodass es für mehr Ziffern geeignet ist.

Antworten (1)

Dies liegt daran, dass der folgende Codeabschnitt versucht, start auf 100.000 für Zahlen gleich oder über 10.000 zu setzen, was zu groß für ein unsigned int ist, das ein 16-Bit ist und nur 0-65535 enthalten kann:

while (start <= input)
    start *= 10;

Das Ändern der Definition wie folgt sollte das Problem beheben:

unsigned long start = 1;

Eine weitere Alternative, um den Code klarer zu machen, besteht darin, stdint.h einzuschließen, damit es wie folgt definiert werden kann und über Compiler hinweg funktioniert:

#include <stdint.h>
uint32_t start = 1;
Woher? Wenn input10.000 ist, wird es startauf 10.000 gesetzt.
Aha! Ich dachte, ein Int würde 32 Bit enthalten, aber das ist ein long! Als Referenz Abschnitt 2.1 .
@abdullahkahraman nein, es setzt es auf 100.000 und der Zähler wird auf start/10 gesetzt.
Wenn die Eingabe 10.000 ist, wird sie startauf 10.000 gesetzt. Wenn die Eingabe jedoch größer als 10.000 ist, wird sie startauf 100.000 gesetzt. Was mache ich falsch?
@abdullahkahraman Es ist <=, nicht <;)
@CamilStaps, kann bei einigen Mikrocompilern eine Falle sein. Ich habe auch die Art und Weise hinzugefügt, wie ich normalerweise vorgehen würde, die portabler ist.
@CamilStaps Aber 10.000 = 10.000 wenn input=10,000.
@abdullahkahraman solange start<=10,000, wird es mit 10 multipliziert. Das letzte Mal, dass es mit 10 multipliziert wird, ist, wenn start=10,000, also wäre das Endergebnis 100.000.