Forum: Compiler & IDEs Absolutbetrag einer 32-Bit-Zahl berechnen


von Andreas (Gast)


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..)

von Heinz (Gast)


Lesenswert?

x = abs(x);

von Stefan (Gast)


Lesenswert?

Andreas schrieb:
> Geht es noch schneller? (z.B. Abfrage des sign-bits durch
> Und-Verknüfung..)

Genau das ist der Weg :-)

Siehe auch http://de.wikipedia.org/wiki/Zweierkomplement

von Floh (Gast)


Lesenswert?

Andreas schrieb:
> Meine Lösungen sehen momentan so aus:
Passt. Lesbar, wartbar, portierbar.

> Geht es noch schneller?
Hast du gemessen dass es zu langsam ist?
Glaub ich dir nicht, Compilerbauer sind auch nicht blöd :-)

von Andreas (Gast)


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

von Andreas (Gast)


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.

von Helfer (Gast)


Lesenswert?

Andreas schrieb:
> int32_t labs(int32_t x)


Rückgabewert sollte uint32_t sein, sonst fällt dir entweder der 
Maximal- oder Minimalwert der int32_t durch.

von Karl H. (kbuchegg)


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.

von Heinz (Gast)


Lesenswert?

Andreas schrieb:
> @Heinz: Das funktioniert eben nicht generell bei allen Compiler
> Manche unterstützen nur 16-bit Variablen.

Ist mir neu! Danke für den Hinweis.

von Andreas (Gast)


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:)

von Sven P. (Gast)


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?

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

@Sven: Hast du gut beobachte - eigentlich sind es 15 Instruktionen:)


Anbei das Assembling:

von Andreas (Gast)


Angehängte Dateien:

Lesenswert?

Hier die Unterschiede

von (prx) A. K. (prx)


Lesenswert?

Schon mal probiert, die Optimierung einzuschalten? Mangelnde Effizienz 
unoptimierten Codes zu bemäkeln ist einigermassen sinnlos.

von Andreas (Gast)


Lesenswert?

@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.

von (prx) A. K. (prx)


Lesenswert?

Andreas schrieb:

> @A.K. Nein, die Optimierung ist vollständig ausgeschaltet.

Yep, das war erkennbar. Folglich ist es völlig sinnlos, wie hier gezeigt 
die Befehle zu zählen.

von Andreas (Gast)


Lesenswert?

Stimmt:)

von Johann L. (gjlayde) Benutzerseite


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!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.