Syntax unterscheidung gerade oder ungerade

Gast #580855
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!
Gast #580858
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
Gast #580869
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
Gast #580871
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 !?
Gast #580876
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.
Persönliche Seite #580880
> 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
Gast #580884
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.
Gast #580918
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?
#580926
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)
#580948
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)

Gast #580951
<sarkasmus>

Dann nimmt man eben die unverschleierte Konstruktion

if ( ( ( x % 2 ) == 1 ) || ( ( x % 2 ) == -1 ) )

anstatt

if ( x & 1 )

</sarkasmus>
Gast #580963
> 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;

Gast #580969
@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.
Gast #580981
> 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.
#581003
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
Gast #581213
> 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).
#581279
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)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 19 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.