Hi, mal ganz schnell eine Frage zwischendurch - gibt es für c einen Syntax mit dem ich "recht einfach" unterscheiden kann ob ein unsigned char gerade oder ungerade ist!? also sowas in der Art: if(x=gerade){....} else{ ich möchte nicht gross rumrechnen deswegen die frage nach einem feinfachen syntaxbefehl! schankeDön!
if(i % 2) // ungerade else // gerade Der Modulo-Operator gibt den Rest einer Ganzzahldivision aus. Wird eine Zahl mit 2 dividiert und der Rest ist 0 -> gerade Ist der Rest 1 -> ungerade
oje, haja klar! - modulo, da war doch was! - hab ich voll verdrängt rolleyes Danke!
ich glaube gandalf und sascha haben die gleiche Idee @stefan - kannst du mir mal "Dein" define erläutern - verstehe das leider nicht :(
Die version von Stefan B. ist wesentlich besser. im prinzip musst du ja nur prüfen ob das LSB(niederwertigste Bit) 1 oder 0 ist. if( (x&1) == 0){ // gerade } else{ // ungerade } ist das gleiche nur als if-bedingung geschrieben lg Azrael
Wenn es unsigned char, gibt das unterste Bit Aufschluß // testen ob unterstes Bit gesetzt, wenn ja, ist term boolisch wahr if (variable & 1) { - ungerade } else { - gerade } Und das Zweierkomplement bei negativen, signed chars dürfte einem keinen Strich durch die Rechnung machen - das war doch: negiert plus eins - oder !?
neg = (~pos) + 1; Bei negativen Werten geht das auch und übrigens nicht nur für unsigned char, sondern alle integer-typen, also char, short, long, long long usw. und eben auch signed. Bei float-Typen (float, double) geht das so nicht.
okay alles klar - dürfte schneller als die modulo gehen! Danke an Euch alle!!!
> Und das Zweierkomplement bei negativen, signed chars dürfte einem keinen > Strich durch die Rechnung machen - das war doch: negiert plus eins - > oder !? Beim Zweierkomplement eines signed char ist es doch so, dass wenn Bit 7 (Nummerierung der Bits 0-7) gesetzt ist, dann hab ich den Wert -128. Die restlichen Bits (0-6) stellen eine positive Zahl dar, welche ich zu dem -128 dann addiere. Somit wäre die Zahl -127 (welche auch ungerade ist) als signed char 10000001. Somit dürfte es gehen, dass man nur das LSB prüft. Wenn es "1" ist --> ungerade, wenn es "0" ist --> gerade. Oder halt Modulo wie schon oben erwähnt :-) Ich persönlich würde das LSB prüfen ;-) Gruß, Thomas
Ich habe übrigens auch schon häufig gesehen, dass der Compiler Moduli mit Zweierpotenzen in entsprechende Und-Verknüpfungen optimiert, aber das hängt mit Sicherheit von Compiler und Architektur ab.
@Florian: ... und davon, ob mit oder ohne Vorzeichen. Bei Datentypen mit Vorzeichen ist es deutlich komplizierter.
Jeder vernünftige Compiler wird aus "x % 2" "x & 1" machen, WENN es erlaubt ist. Diese Optimierung im C-Code vorwegzunehmen halte ich für keine gute Idee.
wieso ist eine Bitmaskierung nicht ratsam @Andreas? Es ist m.M.n. mind. genau so verständlich wie die modulo. Ich selbst sehen darin keinen Unterschied, wenn man einen "schlechten" Compiler hat der das nicht "wegoptimiert" dauert es deutlich länger - somit ist es für mich eine potentielle Bremsstelle im code, oder?
syntax(t)error wrote: > wieso ist eine Bitmaskierung nicht ratsam @Andreas? Weil es die Methode verschleiert. Die Absicht ist: feststellen ob eine Zahl gerade ist. Die Methode ist: Wenn bei einer Division durch 2 ein Rest von 0 übrig bleibt, dann ist die Zahl gerade if( x % 2 == 0 ) drückt exakt die Methode aus. > > Es ist m.M.n. mind. genau so verständlich wie die modulo. Nur wenn du über den Bitaufbau bescheid weist. > > Ich selbst sehen darin keinen Unterschied, wenn man einen "schlechten" > Compiler hat der das nicht "wegoptimiert" dauert es deutlich länger - > somit ist es für mich eine potentielle Bremsstelle im code, oder? Wenn du tatsächlich einen Compiler findest, der diese Optimierung nicht macht, dann schmeiss den Compiler weg und besorg dir einen vernünftigen Compiler den kein Studienanfänger geschrieben hat. Klarheit im Programm geht immer vor Performance (mit Ausnahmen natürlich)
A.K. wrote:
> Dummerweise ist -3 % 2 aber nicht 1, sondern -1.
Und?
-1 ist nicht 0 und daher ist -3 auch nicht gerade.
Oder willst du auf etwas anderes hinaus?
(Glück gehabt: noch mal nach oben gescrollt ergibt, dass
von einem unsigned char die Rede ist. -3 ist daher aussen vor)
<sarkasmus> Dann nimmt man eben die unverschleierte Konstruktion if ( ( ( x % 2 ) == 1 ) || ( ( x % 2 ) == -1 ) ) anstatt if ( x & 1 ) </sarkasmus>
>Weil es die Methode verschleiert
...wofür es Kommentare gibt
> Oder willst du auf etwas anderes hinaus?
Ich will darauf hinaus, das kein Compiler bei Typen mit Vorzeichen (x %
2) einfach zu (x & 1) optimieren darf. Dividieren muss er zwar nicht,
aber bissel komplizierter ist es dennoch. Bei der Division sieht das
beispielsweise für x / (2**n) so aus:
1 | if (x < 0) |
2 | x += (2**N)-1; |
3 | return x >> N; |
P.S.: Wer das 2er Komplement nicht kennt, ist meiner Quelltexte nicht würdig ;-)
@A.K.: Auf vielen Architekturen gibt es die Unterscheidung zwischen logical shift right und artihmetic shift right. Bei letzterem wird dann von links nicht mit Nullen, sondern dem ursprünglichen höchsten Bit gefüllt. Dann bleibt das ganze wieder konsistent. Der C-Compiler allerdings macht immer ein logical shift right, so dass Dein Konstrukt notwendig wäre, allerdings ist es vermutlich besser tatsächlich so was wie y = x / ( 1 << N ) zu schreiben, da der Compiler das vermutlich zu asr x, N vereinfachen würde.
> Bei letzterem wird dann von links nicht mit Nullen, > sondern dem ursprünglichen höchsten Bit gefüllt. > Dann bleibt das ganze wieder konsistent. Nein. Die C Division rundet gegen Null, der arithmetische Shift gegen Minus Unendlich.
Florian wrote:
> Der C-Compiler allerdings macht immer ein logical shift right
Nein, er schiebt immer richtig (typabhängig):
Bei unsigned schiebt er ne 0 rein.
Bei signed schiebt er das höchstwertige Bit (Vorzeichenbit) weiter.
Peter
> Glück gehabt: noch mal nach oben gescrollt ergibt, dass > von einem unsigned char die Rede ist. -3 ist daher aussen vor Pech gehabt. Die integer promotion von C bringt es mit sich, dass solche Ausdrücke als "int" gerechnet werden. Wenn der Compiler das erst zu 16 oder 32 Bits erweitert, dann geht ihm auf dem Weg allzu leicht die Information verloren, dass negative Werte nicht vorkommen können. Und genau das passiert mindestens bei den PC-Compilern von Microsoft und Walter Bright (Digital Mars).
A.K. wrote: >> Glück gehabt: noch mal nach oben gescrollt ergibt, dass >> von einem unsigned char die Rede ist. -3 ist daher aussen vor > > Pech gehabt. Die integer promotion von C bringt es mit sich, dass solche > Ausdrücke als "int" gerechnet werden. Grummel, grummel. Das Glück ist ein Vogerl (alte österr. Volksweisheit)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.