Absolutbetrag einer 32-Bit-Zahl berechnen

Gast #2557809
Lesenswert?

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 #2557867
Lesenswert?

@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 #2557871
Lesenswert?

@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.
#2557895
Lesenswert?

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 #2557933
Lesenswert?

@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 #2557941
Lesenswert?

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?
Persönliche Seite #2558339
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren