Ist eine Zahl gerade?

mamarulez

Mitglied
Hallo!

ich hab mal eine kurze Frage:

ich habe eine Funktion mit zugehöriger Hauptschleife geschrieben, was einfach untersucht ob eine Zahl gerade oder nicht gerade ist.

Hier kommt erstmal der Quelltext:

Code:
bool IstZahlGerade ( int Zahl )
{
	int		i;
	for ( i = 0; i <= 1000; i = i += 2 )
	{
		if	( i == Zahl )
		return true;
		else
		return false;
	}
}

void main ( void )
{
	//AufPrimzahlTesten ( 2, 10 );
	if ( IstZahlGerade ( 4 ) == true) cout<<"4 ist gerade\n";
	else cout<<"4 ist ungerade\n";
}

Also, mein Problem ist, dass im Programm die Zahl 4 als ungerade bezeichnet wird! Anscheinend heist es, dass alle Zahlen ungerade seien, da ich, als ich später die 5 einsetzte es auch (diesmal zufällig richtig!) hieß, dass auch 5 ungerade sei.

Kann mir wer helfen?

Danke im Vorraus!
 
Wieso nicht einfach mit:
Code:
int iNum = 5;
if (iNum % 2 == 0) {
    printf( "%i ist gerade", iNum );
} else {
    printf( "%i ist nicht gerade", iNum );
}
 
Servus!

Geht auch so:

Code:
#include <iostream>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[])
{
for (int i = 0; i < 10000;i++){
    cout << "i: " << i << " ist gerade: " << !(i & 1) << "\n" ;
}
  system("PAUSE");	
  return 0;
}

Gruß tom
 
Zu überprüfen ob eine Zahl gerade oder ungerade ist, geht ganz einfach. Man braucht nur überprüfen ob das erste Bit 1 oder 0 ist. Das funktioniert aber ausschließlich bei Datentypen, die nur ganze Zahlen darstellen können (w.z.B. int, long, short, __int64 etc.). D.h. bei floats und doubles würde das nicht funktionieren, da diese Datentyp eine spezielle Formatierung im Speicher haben. Auch wenn eine Variable dieses Datentyps eine gerade Zahl enthält würde es höchstwahrscheinlich nicht funktionieren. Ist aber nur eine Annahme; verwendet aber zur Sicherheit Datentypen, die für ganze Zahlen da sind.

Warum funktioniert das?

Nun lasst uns einfach die Zahlen 0 -15 in Binär aufschreiben:

0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = 10
1011 = 11
1100 = 12
1101 = 13
1110 = 14
1111 = 15

Wenn wir genau hinschauen, dann bemerken wir, dass das erste Bit bei allen geraden Zahlen 0 ist, und bei ungeraden Zahlen 1.

Deine IstZahlGerade-Funktion müsste daher folgendermaßen aussehen:

Code:
bool IstZahlGerade ( int Zahl )
{
  if( (Zahl & 1) == 0)
    return true;
  else
    return false;
}
Wir brauchen das erste Bit einfach nur mit einer binären Und-Operation isolieren, und auf 0 prüfen. Falls das zutrifft ist die Zahl gerade.
Man bezeichnet das, was in der If-Abfrage in den Klammern steht auch als "Maskierung". Ich gebe dir zwei Beispiele dazu:

Wenn ich eine binäre Zahl, 0110 0101 (8Bit, könnte ein character sein), habe und die höherwertigen 4 Bits isolieren wollte, dann müsste ich diese Zahl einfach mit 1111 0000 und-verknüpfen. Das Ergebnis wäre 0110 0000.

Oder wenn du folgende Zahl hast: 1001 1011 1101 0011 und das niederwertige Byte erhalten willst, dann musst du diese Zahl mit 0000 0000 1111 1111 und-verknüpfen.
Das Ergebnis: 0000 0000 1101 0011

Wir sehen also, dass bei einer Und-Verknüpfung die 0 immer "gewinnt".
 
Zuletzt bearbeitet:
Ich denke mit dem Modulus sollte es auch funktionieren, aber die Methode die ich angeführt habe finde ich persönlich besser, da sie sicher schneller bearbeitet wird. Eine Und-Verknüpfung macht jeder Prozessor mit Links (es ist praktisch ein eigener Hardwarebefehl), aber im Vergleich dazu wird jeder Prozessor bei einer Modulu-Operation ein wenig länger brauchen. Nehme ich zumindest an.

Es ist klar, dass nicht bei jeder Anwendung Schnelligkeit wichtig ist, aber davon zu wissen ist ja sicherlich was Gutes.
 
@Aziz:
Wenn man %2 (sprich Modulo 2) schreibt, ist der Compiler schon schlau genug und wandelt es dir in den von dir beschriebenen &1 (sprich bitweise UND mit 1) um. Beide Methoden sind also identisch und damit auch gleich schnell
 
Zurück