Seite 1 von 1
[C++]abs(int x) - 64 Bit(long long) Version
Verfasst: Mi Dez 31, 2014 4:37 pm
von darksider3
Nabönd,
Situation: Aktuell möchte ich so viele Rechenfunktionen wie möglich aus der math.h/cmath nach schreiben.
Problem: Ich habe gerade die Funktion abs(int x) fertig bekommen, und möchte dies nun auch 64 bit(long long) tauglich machen. Folgendes wäre der Int-Code:
Code: Alles auswählen
int abs_32(int x) // use if 32 bit
{
return (1 - (((x >> 31) & 0x1) << 1)) * x;
}
Getestet, und Funktioniert auch erst mal. Um das mit long long(64 bit, wie gesagt) hinzukriegen, dachte ich mir, das man "einfach" die 31 in der Anweisung auf 63 umändert, um so das äquivalent zu finden. Nur ist die Frage, ob das mal eben "so simpel" von statten geht, also auch funktioniert..
Wie seht ihr das? Oder würdet ihr das anders machen?
(Nebenbei, ich versuche keine C/C++-Internen Funktionen bis auf Operatoren zu bentuzen..)
Danke schon mal,
Grüße

Re: [C++]abs(int x) - 64 Bit(long long) Version
Verfasst: Mi Dez 31, 2014 5:51 pm
von mfro
Kann man so machen, muß man aber nicht.
Code: Alles auswählen
int32_t abs32(int32_t val)
{
if (val > 0)
return val;
return -val;
}
liefert dieselben Ergebnisse, nur höchstwahrscheinlich wesentlich effizienter (dein Nachbar kann jetzt zwei Bilder aufhängen) und Du verstehst auch morgen noch, was Du da gemacht hast.
Überlaß' es besser deinem Compiler, ob er lieber Bitfummeln will oder negiert - der weiß besser, was wann besser ist (manche Prozessoren haben dafür einen entsprechenden Maschinenbefehl).
Re: [C++]abs(int x) - 64 Bit(long long) Version
Verfasst: Mi Dez 31, 2014 5:57 pm
von cloidnerux
(Nebenbei, ich versuche keine C/C++-Internen Funktionen bis auf Operatoren zu bentuzen..)
Zwei Dinge musst du hier verstehen:
Wie negative Zahlen im Computer funktionieren(Zweierkomplement)
und wie die Bitbanging-Operatoren funktionieren(<< >> & | ^).
ansonsten würde ich noch erwähnen, dass die Implementation von dir mitunter zu langsam ist gegenüber einer Variante mit if.
Re: [C++]abs(int x) - 64 Bit(long long) Version
Verfasst: Mi Dez 31, 2014 7:46 pm
von Xin
darksider3 hat geschrieben:Nabönd,
Situation: Aktuell möchte ich so viele Rechenfunktionen wie möglich aus der math.h/cmath nach schreiben.
Problem: Ich habe gerade die Funktion abs(int x) fertig bekommen, und möchte dies nun auch 64 bit(long long) tauglich machen. Folgendes wäre der Int-Code:
Code: Alles auswählen
int abs_32(int x) // use if 32 bit
{
return (1 - (((x >> 31) & 0x1) << 1)) * x;
}
Getestet, und Funktioniert auch erst mal. Um das mit long long(64 bit, wie gesagt) hinzukriegen, dachte ich mir, das man "einfach" die 31 in der Anweisung auf 63 umändert, um so das äquivalent zu finden. Nur ist die Frage, ob das mal eben "so simpel" von statten geht, also auch funktioniert..
Funktioniert.
Das ist wirklich eine interessante Variante, um das Vorzeichen zu ändern. Da ist mfros Variante regelrecht langweilig gegen, aber zugegebenermaßen leichter zu lesen.
Versuchen wir einen Kompromiss. ^^
Du prüfst mit ((x >> 31)&0x1, ob das 31. Bit eingeschaltet ist. Wenn dem so ist, Multiplizierst Du mit 1-2, ansonsten mit 1-0.
Machen wir doch einen Kompromiss:
Code: Alles auswählen
int abs_32(int x) // use if 32 bit
{
if( x & (1<<31) ) // negative Zahl
return -x;
else return x;
}
Da sind die Bits noch drin.... da man aber eigentlich nicht weiß, was ein int ist (könnte ja auch 16 oder 64 Bit breit sein), ist mfros Variante vermutlich die kompatibelste aller möglichen Varianten.
Anyway... der Ausdruck mag langsam sein, aber er bekommt einen Zusatzpunkt in der B-Note: Durchaus eine klevere und ausgefallene Lösung. ^^