Absolutbetrag einer 32-Bit-Zahl berechnen

Gast #2557809
Da im letzten Thread ein paar super Hinweise kamen hat es mich grad 
motiviert noch eine Frage zu stellen:)

Manche Compiler können es wahrscheinlich schon von Haus aus - aber eben 
nicht alle.

Ich möchte den Absolutbetrag einer int32_t möglichst schnell, aber ohne 
Assembler, und mit Standard-C berechnen (Also keine compilerspezifischen 
Code, der dann nicht portierbar ist..).

Meine Lösungen sehen momentan so aus:
1
// Lösung 1:
2
int32_t labs(int32_t x)
3
{
4
  if (x<0) return -x;
5
      else return x;
6
}
7

8
// Lösung 2:
9
#define labs(x) ((x) >= 0 ? (x) : -(x))


Geht es noch schneller? (z.B. Abfrage des sign-bits durch 
Und-Verknüfung..)
Gast
@Heinz: Das funktioniert eben nicht generell bei allen Compiler
Manche unterstützen nur 16-bit Variablen.

@Stefan:
Die Zweierkomplementbildung ist mir schon klar. Ich habe mir aber 
gedacht, es könnte Kompatiblitätsprobleme geben, da die Bytes nicht in 
allen Betriebssystemen gleich angeordnet sind. Vielleicht ist es aber 
nur eine Befürchtung:)
1
#define labs2(x) ((x&0x80000000) == 0 ? (x) : -(x))

dauert aber gleich lang - bei einem dsPIC z.B. auch 19 Instruktionen
Gast
@Floh: Erst jetzt gesehen)

Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen. 
Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier 
kommen ja immer wieder super Anregungen.
Andreas schrieb:
> Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen.
> Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier
> kommen ja immer wieder super Anregungen.

Lerneffekt?

Überlass das dem Compiler bzw. den Funktionen die du in der Runtime 
Library mitbekommen hast.

Sich da über 2-er Komplement den Kopf zu zerbrechen lohnt nicht.
So wie es sich meistens nicht lohnt, über derartige Klein-Klein 
Optimierung den Kopf zu zerbrechen. Benutze die richtigen Datentypen, 
benutze gute Algorithmen und den Rest überlass dem Compiler. Denn wie 
sagte schon Floh: Compilerbauer sind auch keine Trottel.

Es bringt nix, einen Bubblesort auf den letzten Taktzyklus hin zu 
optimieren, wenn ihn ein unoptimierter Quick-Sort aus dem Stand schlägt.
Gast
@Helfer: Ja, stimmt, beim kleinsten Wert hätte man ein Problem

@Karl Heinz: Ja, das stimmt schon was du sagst, das 
Optimierungspotenzial liegt ganz sicher wo anderst. Eben auch in 
durchdachten Strukturen:):)
Trotzdem: Ineffiziente Elementarfunktion können bei häufigem Aufruf auch 
ins Gewicht fallen. Ebens ist auch interessant, wie andere elementare 
Funktionen umsetzen. ..und eine Info habe ich ja nun wieder gewonnen 
nämlich dass die aktuelle Variante einen guten Weg darstellt:)
Gast
Andreas schrieb:
> @Floh: Erst jetzt gesehen)
>
> Ja, ich habe gemessen. Es dauert bei einem 16bit dsPic 19 Instruktionen.
> Es geht ja schnell. Mir geht es hier mehr um den Lerneffekt und hier
> kommen ja immer wieder super Anregungen.
Könntest du mal ein Assembler-Listing davon übersetzen?

19 Instruktionen kommt mir ziemlich viel vor, eventuell stecken da noch 
Instruktionen zum Laden und Speichern zwischen Register und RAM drin?
Gast
@A.K. Nein, die Optimierung ist vollständig ausgeschaltet.

Wieviel man aber bei maximaler Speedoptimierung herausholt, das kann ich 
nicht ermitteln. Ich glaube aber, es macht noch einiges aus.
Persönliche Seite
Andreas schrieb:
> @Heinz: Das funktioniert eben nicht generell bei allen Compiler
> Manche unterstützen nur 16-bit Variablen.
>
> @Stefan:
> Die Zweierkomplementbildung ist mir schon klar. Ich habe mir aber
> gedacht, es könnte Kompatiblitätsprobleme geben, da die Bytes nicht in
> allen Betriebssystemen gleich angeordnet sind.

C macht keine Angabe darüber, wie negative Zahlen dargestellt werden! 
Zweierkomplement ist üblich, aber nicht zwingend -- was auch der Grund 
dafür ist, daß signed-Überlauf in C undefined ist und Compiler das 
ausnutzen können.

Mit der if/else vanilla-Variante bist du auf der sicheren Seite; Problem 
stellt lediglich INT32_MIN dar, da im Zweierkomplement -INT32_MIN nicht 
darstellbar ist und auf INT32_MIN abgebildet wird. Will man das abfangen 
(etwa durch Abbildung auf INT32_MAX), dann muss das vor der 
Betragsbildung geschehen! Versucht man es danach, darf der Compiler 
verwenden, daß signed-Überlauf undefined ist!

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.