gibt es SGN-Funktion in C?
-
TactX schrieb:
Ist ja aber trivial zu implementieren.
meinst du?
-
ich hab jetzt einen code gefunden:
#define SGN(x) (x == 0 ? 0 : x > 0 ? 1 : -1)
ist schneller wie z.B:
#define SGN(x) ((x>0)-(x<0))
-
TheShadow2000 schrieb:
ich hab jetzt einen code gefunden:
#define SGN(x) (x == 0 ? 0 : x > 0 ? 1 : -1)
ist schneller wie z.B:
#define SGN(x) ((x>0)-(x<0))
glaub' ich nicht. für konstante werte vielleicht, aber letzteres ist immerhin 'branch free' (naja, doch nicht immer)
:xmas2:
-
ich hab es getestet - 1. version war 10x schneller (mit mingw).
liegt wohl an integer-arithmetik, da bei der 2. version 2 werte abgezogen werden - während die 1. nur werte vergleicht...
-
ich kriegs leider nur für c++ hin:
#include <memory> class Sgn { private: template<class T> static std::auto_ptr<Sgn> createSignObjectByNr( T n ); public: virtual int getSign() const = 0; template<class T> static T sign( T n ); }; class SgnPositiv : public Sgn { public: int getSign() const { return( 1 ); } }; class SgnNegativ : public Sgn { public: int getSign() const { return( -1 ); } }; class SgnNull : public Sgn { public: int getSign() const { return( 0 ); } }; template<class T> std::auto_ptr<Sgn> Sgn::createSignObjectByNr( T n ) { std::auto_ptr<Sgn> ret( new SgnNull() ); if( n < T(0) ) ret = std::auto_ptr<Sgn>( new SgnNegativ() ); if( n > T(0) ) ret = std::auto_ptr<Sgn>( new SgnPositiv() ); return( ret ); } template<class T> T Sgn::sign( T n ) { std::auto_ptr<Sgn> sobj = Sgn::createSignObjectByNr<T>( n ); return( T( sobj.get()->getSign() ) ); } // test #include <iostream> int main() { std::cout << "-5 -> " << Sgn::sign( -5 ) << std::endl; std::cout << "+6 -> " << Sgn::sign( 6 ) << std::endl; std::cout << " 0 -> " << Sgn::sign( 0 ) << std::endl; }
-
ten schrieb:
TactX schrieb:
Ist ja aber trivial zu implementieren.
meinst du?
Jup.
-
Only-Olli: ich werde es mal bei thedailywtf melden.
-
Only-Olli schrieb:
ich kriegs leider nur für c++ hin:
:open_mouth: :open_mouth: :open_mouth: :open_mouth:
macht man das wirklich so in c++
mein vorschlag (für ints <= 32 bit):
#define SGN(x) (((x)>>30)|1)
-
@Only-Olli... wow das ist overhead pur...
-
ten schrieb:
Only-Olli schrieb:
ich kriegs leider nur für c++ hin:
:open_mouth: :open_mouth: :open_mouth: :open_mouth:
macht man das wirklich so in c++
mein vorschlag (für ints <= 32 bit):
#define SGN(x) (((x)>>30)|1)
Deine Methode ist krasser!
Bei negativen Zahlen liefert sie immer 3 (int = 32 Bit)
Bei positiven Zahlen liefert sie 1 und wenn x == 0 auch 1
-
egon2 schrieb:
Bei negativen Zahlen liefert sie immer 3 (int = 32 Bit)
dann haste was falsch gemacht
egon2 schrieb:
...und wenn x == 0 auch 1
richtich, 'ne 0 hat ja auch kein vorzeichen.
da kann dieses makro auch nix für
-
ten du troll, mach die leute nicht wuschig!
das vorzeichenbit bei 32 bit signed ints ist (1<<31) und wenn einer mit embedded geschichten kommt, wirst du geteert und gefedert.
-
@ten: wollte er nicht auch noch wissen, ob seine zahl ne 0 ist?
Input: -1
Output: -1Input: 0
Output 1Input 1
Output 1und so fehlt doch noch was in deinem makro
-
c.rackwitz schrieb:
das vorzeichenbit bei 32 bit signed ints ist (1<<31)...
ist jemand anderer meinung?
Jay schrieb:
@ten: wollte er nicht auch noch wissen, ob seine zahl ne 0 ist?
Input: -1
Output: -1Input: 0
Output 1Input 1
Output 1und so fehlt doch noch was in deinem makro
ja, stimmt.
also entweder
- man vermeidet, dass dam makro eine 0 gegeben wird
oder
- das 'aus 0 mach 1' hat keinen negativen effekt (dann kann man's so lassen)
oder
- man baut ein 'conditional' ins makro ein: #define SGN(x) ((x)?(((x)>>30)|1):0)
-
Man muss nicht alles mit Bitshifts machen
-
Voll optimiert ist meine "C++-Methode" (die natürlich Schwachsinn ist ^^), nur 3mal langsamer als das SGN-Makro mit den zwei Vergleichen!... Jah und jetzt kommt ihr!