C Kommastellen verwerfen

  • DerSchatten schrieb:

    Quellcode

    1. void Print(uint16_t num)
    2. {
    3. uint8_t i=0;
    4. uint8_t j;
    5. if (num>9999) return;
    6. while (num)
    7. {
    8. digits[i]=num%10;
    9. i++;
    10. num=num/10;
    11. }
    12. for (j=i;j<4;j++) digits[j]=0;
    13. }
    Alles anzeigen

    Die zweite Zählvariable ist auf jeden Fall überflüssig, aber das ist ne Kleinigkeit. Vielleicht generell -- ich finde so eine Mischung deutsch/englisch wird schnell unübersichtlich. Aber das ist wohl auch Geschmackssache.

    Mac Bacon schrieb:

    In C ist das Ergebnis der Operation "Negativer Wert nach rechts geshiftet" undefiniert. Das wird hier vermutlich nicht das Problem sein, kann einem aber den Tag verderben. [AxelStoll] Muss man nur wissen [/AxelStoll].

    Zeile 131 wäre also eine mögliche Problemstelle? Kann es passieren, dass das Vorzeichenbit mitgeschoben wird? Nett...

    THaase schrieb:

    Zirias schrieb:

    Sind mir zu viele arithmetische Operationen, nur dafür, das möglichst tricky aussehen zu lassen :p
    Der Code kann nicht der selbe sein .... man müsste sich aber mal den output anschauen um zu sehen was schneller ist ... bne/beq bzw. jmp sind recht lahm wenn ich mich da recht erinnere ...

    Prinzipiell kann der schon derselbe sein, wenn der Compiler für den einen Teilausdruck erkennt, dass die Wertemenge nur 2 Elemente hat. Habe jetzt gar nicht darauf geachtet, auf welcher Architektur wir hier sind -- aber Branches sollen lahm sein? Das wäre schlecht. Kann man (f<0) überhaupt ohne Branch auswerten? Würde mich wundern, und dann erstmal mit weiteren Rechnungen anzufangen, anstatt nach dem Branch direkt die gewünschte Operation auszuführen ist sicher nicht besser ;)

    Die Diskussion über Runden und/oder Nachkommastellen abschneiden scheint aber eh unpassend, in dem ganzen Code gibt es ja nur Ganzzahlen ?(

    DerSchatten schrieb:

    Mit int32_t funktioniert.

    Wenn ich das jetzt richtig verstanden habe müsste damit wohl auch das Problem der zu lange angezeigten 0 gelöst sein, oder?
  • Ja, damit funktioniert die Zählung.

    Welche Variable ist überflüssig?
    j ?

    Das ist ein Teil des Multiplexing um das 4x7-Segment anzusteuern.


    This function breaks apart a given integer into separate digits
    and writes them to the display array i.e. digits[]

    -= Neu in meiner Sammlung =-
    -= Modding =-


    Nichts hält länger als ein Provisorium
  • DerSchatten schrieb:

    Welche Variable ist überflüssig?
    j ?

    Richtig. Kannst einfach i weiterzählen, z.B. so:

    Quellcode

    1. void Print(uint16_t num)
    2. {
    3. uint8_t i=0;
    4. if (num>9999) return;
    5. while (num)
    6. {
    7. digits[i++]=num%10;
    8. num=num/10;
    9. }
    10. while (i<4) digits[i++]=0;
    11. }
    Alles anzeigen

    Übrigens, für Zählvariablen am besten einfach immer int nehmen, das ist in der Regel die native Wortlänge der Architektur (oder weniger, vor allem bei 64bittern) und potentiell am schnellsten. Gibt natürlich Ausnahmen (8bit) :D
  • Ganz genau betrachtet ist dann sogar am besten, uint_fast16_t Typen und Konsorten zu nehmen, die sollten dann wirklich am schnellsten sein. Ist aber vielleicht in dem Zusammenhang dann doch Korinthen und so ;)
    ────────────────────────────────────────────────────────────
    Time of Silence - Time of Silence 2 Development Blog
    ────────────────────────────────────────────────────────────
  • Claus schrieb:

    Ganz genau betrachtet ist dann sogar am besten, uint_fast16_t Typen und Konsorten zu nehmen, die sollten dann wirklich am schnellsten sein. Ist aber vielleicht in dem Zusammenhang dann doch Korinthen und so ;)

    Trotzdem interessant, den Typ kannte ich noch nicht, klingt aber wie der "bessere int" zu dem Zweck. Wurde der auch mit C99 eingeführt?
  • Ja, C99. Aber MSVC kann's trotzdem auch ;) ...
    ────────────────────────────────────────────────────────────
    Time of Silence - Time of Silence 2 Development Blog
    ────────────────────────────────────────────────────────────
  • Noch eine kleine Korrektur, jetzt sollte es korrekt zählen:

    Quellcode

    1. valganz += encode_read();
    2. if (valganz < 0)
    3. valganz += 40000;
    4. else if (valganz >= 40000)
    5. valganz -= 40000;
    6. val = valganz / 4;

    valganz wird bei Überlauf nicht auf 0 gesetzt, sondern um -40000 nach unten korrigiert. Macht aber nur einen Unterschied, wenn der Zähler um mehr als eins auf einmal hochgezählt wird.

    Und dann könnte man natürlich noch Konstanten für Divisor und max. Zählerstand definieren, falls man mal durch was anderes als 4 teilen will...
    AC/64 - C64 Umbau auf 9V Wechselspannung: Thread | Homepage
    Jocopod - Joystick to Controlport Dongle: Thread | Homepage
  • Du meinst die Abfrage auf > 9999 in Print()?
    Würde ich drinlassen zur Sicherheit. Ansonsten überschreibt Dir Print() was im Speicher, wenn Du doch mal aus Versehen versuchst einen Wert mit mehr als 4 Ziffern zu konvertieren (der 'digits' Puffer hat ja nur 4 Elemente).
    Man könnte Print() natürlich auch so ändern, dass bei über 9999 ein Overflow oder nur die unteren 4 Ziffern angezeigt werden etc.
    AC/64 - C64 Umbau auf 9V Wechselspannung: Thread | Homepage
    Jocopod - Joystick to Controlport Dongle: Thread | Homepage
  • Nein, mit meinem letzten Code-Schnipsel läuft der Zähler nicht weiter, er bleibt immer zwischen 0 und 39999, was dann durch 4 geteilt 0 ... 9999 ergibt.
    Kann also nix passieren, die Abfrage in Print() schlägt letztlich nie zu, solange niemand an den Werten rumfummelt. Ich würde die Abfrage trotzdem drinlassen, damit die Funktion einfach nix kaputt machen kann, auch wenn man sie mal falsch aufruft.
    AC/64 - C64 Umbau auf 9V Wechselspannung: Thread | Homepage
    Jocopod - Joystick to Controlport Dongle: Thread | Homepage
  • Benutzer online 1

    1 Besucher