Geradzahligkeit ermitteln
-
Ist vlt. etwas billig aber gibt es eine fertige Funktion mit der man eine Zahl auf gerade/ungerade prüfen kann? Ansonsten fällt mir nur ein zu vergleichen, ob am Zahlenende 0,2,4,6 oder 8 steht und das dann mit true oder false ausgeben.
-
bool is_even(int num) { return num%2==0; }
-
inline bool isEven (int num) { return !(num & 1); }
-
Na das ging ja fix, danke!
-
Weisst du auch, was die Funktion macht?

-
Dividiert num durch 2 und gibt den Rest zurück. Rest = 0 gerade Rest nicht 0 ungerade.
Ist das sinngemäß richtig?
-
Ist es, ja. Die Alternative von audacia schaut einfach direkt, ob das letzte Bit gesetzt ist, so gesehen ist Shades Variante allgemeingültiger. Aber du siehst, die letzte Ziffer im Dezimalsystem ist völlig irrelevant.
-
audacias Variante ist wahrscheinlich nicht einmal schneller, auch wenn direkt mit Bits hantiert wird (wegen Compileroptimierung).
-
....
-
Nexus schrieb:
audacias Variante ist wahrscheinlich nicht einmal schneller, auch wenn direkt mit Bits hantiert wird (wegen Compileroptimierung).
ACK
Dafür ist sie "geekiger"
-
Das macht der Vc++ 2005 draus (release build):
Shadows Variante:
_is_even PROC ; _num$ = eax ; 4 : return num%2==0; and eax, -2147483647 ; 80000001H jns SHORT $LN3@is_even dec eax or eax, -2 ; fffffffeH inc eax $LN3@is_even: neg eax sbb eax, eax add eax, 1 ; 5 : } ret 0 _is_even ENDPaudacias Variante:
_is_even2 PROC ; _num$ = eax ; 9 : return !(num&1); not eax and eax, 1 ; 10 : } ret 0 _is_even2 ENDPEs wird zwar in der ersten die Division wegoptimiert, aber wirklich schön isses trotzdem nicht.
-
hustbaer schrieb:
Dafür ist sie "geekiger"

Und schöner formatiert. SCNR

-
Modulo-Operationen sind leider immer recht teuer. Da kann der Compiler auch nicht viel dran optimieren.
-
Also bei MOD 2^n kann ein Compiler sehr wohl optimieren.
@vlad_tepesch: Optimierer war auf was eingestellt?
-
Tachyon schrieb:
Modulo-Operationen sind leider immer recht teuer. Da kann der Compiler auch nicht viel dran optimieren.
TS-MacBook-Pro:Code ts$ cat test.c int is_even(int num) { return num % 2 == 0; } int is_even2(int num) { return !(num&1); } TS-MacBook-Pro:Code ts$ gcc -O3 -c test.c -S TS-MacBook-Pro:Code ts$ cat test.s .text .align 4,0x90 .globl _is_even _is_even: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax xorl $1, %eax andl $1, %eax leave ret .align 4,0x90 .globl _is_even2 _is_even2: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax xorl $1, %eax andl $1, %eax leave ret .subsections_via_symbols TS-MacBook-Pro:Code ts$ gcc --version i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5488) Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.also zumindest mein gcc kann das problemlos optimieren...
-
also zumindest mein gcc kann das problemlos optimieren...
Naja, optimiert ist auch was anderes!
@vlad_tepesch: Optimierer war auf was eingestellt?
Full optimization; Favor fast Code
-
vlad_tepesch schrieb:
Naja, optimiert ist auch was anderes!
Was meinst du?
Zuhause werde ich es dann beim vc++08 mal testen und die ergebnisse posten. kann mir irgendwie nicht vorstellen dass es moderne compiler gibt die so doof sind dass sie das nicht optimieren können.
bei dem von dir geposteten asm code wird sehr komisch herumgerechnet um am ende wieder das selbe zu machen was er bei der anderen version macht:
add eax, 1
-
Shade Of Mine schrieb:
vlad_tepesch schrieb:
Naja, optimiert ist auch was anderes!
Was meinst du?
Das nenn ich optimal:
_is_even2 PROC ; _num$ = eax ; 9 : return !(num&1); not eax and eax, 1 ; 10 : } ret 0 _is_even2 ENDPZuhause werde ich es dann beim vc++08 mal testen und die ergebnisse posten.
Was ich gepostet hatte stammt doch vom vc8.
vlad_tepesch schrieb:
Das macht der Vc++ 2005 draus (release build):
-
bool is_even(int num) { return num%2u==0; }
-
vlad_tepesch schrieb:
Das nenn ich optimal:
_is_even2 PROC ; _num$ = eax ; 9 : return !(num&1); not eax and eax, 1 ; 10 : } ret 0 _is_even2 ENDPVerstehst du den asm Code überhaupt?
Nichts anderes macht der gcc. bits invertieren und dann testen ob das rechteste bit eine 1 ist.ob du dafür not oder xor verwendest ist egal. es wird seinen grund haben warum der gcc hier lieber xor und der vc++ lieber not nimmt.
und nach dem xor/not wird ein and gemacht. fertig.
ich habe dem gcc aber verboten die funktion inline zu definieren so wie du es dem vc++ erlaubt hast - was dazu führt dass der code leicht verfälscht ist, da es schwerer ist die genauen kosten zu berechnen.
deshalb muss bei mir der gcc erst den parameter vom stack popen und in ein register schieben. So kann ich genau die kosten der Funktion erkennen und kann garantieren dass nichts wegoptimiert wird was generell nötig ist aber für den aktuellen fall uninteressant ist.
zB wenn der compiler weiss dass num immer 2 ist, kann er die funktion zu einem
mov eax, 1
machen und fertig. aber das wäre ja doof, deshalb verbiete ich ihm diese optimierungen.
-
Und wie langweilig

camper hat wie immer recht. dumme sache das. mach mal fehler!!PUBLIC _is_even ; Function compile flags: /Ogtpy ; File d:\code\testili\testili\extern.cpp ; COMDAT _is_even _TEXT SEGMENT _num$ = 8 ; size = 4 _is_even PROC ; COMDAT ; 2 : return num%2u == 0; mov eax, DWORD PTR _num$[esp-4] not eax and eax, 1 ; 3 : } ret 0 _is_even ENDP _TEXT ENDS PUBLIC _is_even2 ; Function compile flags: /Ogtpy ; COMDAT _is_even2 _TEXT SEGMENT _num$ = 8 ; size = 4 _is_even2 PROC ; COMDAT ; 6 : return !(num&1); mov eax, DWORD PTR _num$[esp-4] not eax and eax, 1 ; 7 : } ret 0 _is_even2 ENDP _TEXT ENDSsehr dummer vc++ aber. denn er koennte eigentlich wissen dass 2 nicht negativ sein kann...