Wie überprüfe ich, ob eine ganze Zahl gerade oder ungerade ist? [closed]

Lesezeit: 7 Minuten

Benutzeravatar von chustar
chustar

Wie kann ich überprüfen, ob eine bestimmte Zahl in C gerade oder ungerade ist?

  • Die Version, die bitweise und (&) verwendet, ist viel effizienter als die Modulo-Version (%). Sie sollten die von Ihnen ausgewählte als richtige Antwort ändern.

    – Stefan Russek

    2. Oktober 2008 um 11:11 Uhr

  • Es ist unwahrscheinlich, dass es eine Rolle spielt – Streit ist eine Konstante. Einfach für den Optimierer

    – MSalter

    2. Oktober 2008 um 11:20 Uhr

  • Auch die Lesbarkeit spielt dabei eine Rolle.

    – Brian G

    2. Oktober 2008 um 12:39 Uhr

  • In eingebetteten Anwendungen (die Welt, in der ich die meiste Zeit mit Programmieren verbringe) haben einige Prozessoren sehr primitive arithmetische Einheiten und können Divisions-/Modulus-Operationen nicht einfach ausführen. Aus diesem Grund verwende ich stattdessen normalerweise die bitweise-und-Methode. Auf der CPU eines modernen Desktops ist dies jedoch nicht der Fall.

    – bta

    26. Februar 2010 um 23:04 Uhr

  • Ich fand die Modulo-Operation nie einfacher zu verstehen. Als ich zum ersten Mal gerade oder ungerade bestimmen musste, kam mir als erstes die bitweise Maske in den Sinn. Es ist etwas natürlich, da wir dazu neigen, dies von Hand zu tun, indem wir uns die niedrigstwertige Ziffer ansehen, um zu sehen, ob sie in {0 2 4 6 8} oder {1 3 5 7 9} steht. Das bedeutet direkt, auf das niederwertigste Bit zu schauen, um zu sehen, ob es 0 oder 1 ist.

    – P Papa

    27. Februar 2010 um 13:50 Uhr

Benutzeravatar von SCdF
SCdF

Ihr seid viel zu effizient. Was Sie wirklich wollen, ist:

public boolean isOdd(int num) {
  int i = 0;
  boolean odd = false;

  while (i != num) {
    odd = !odd;
    i = i + 1;
  }

  return odd;
}

Wiederholen Sie für isEven.

Bei negativen Zahlen funktioniert das natürlich nicht. Aber mit Brillanz kommt Opfer…

  • Wenn Sie eine Argument-Ausnahme auf negative Werte werfen und in der Dokumentation vermerken, dass diese Funktion O (N) ist, dann würde ich das gut machen.

    – Jeffrey L Whitledge

    2. Oktober 2008 um 15:20 Uhr

  • Die Enterprise-Version müsste XML verwenden. Natürlich hätte man heutzutage einen Webservice, den man abfragen könnte

    – Martin Beckett

    27. Februar 2010 um 2:24 Uhr

  • Sie sollten dies mit einer Nachschlagetabelle optimieren.

    – Weeble

    27. Februar 2010 um 2:45 Uhr

  • Ich bin so ein Mönch, musste deinen 6.999 Wiederholungen +1 in ein neues Jahrtausend geben

    – Eran Medan

    10. Mai 2012 um 5:38 Uhr

  • Das ist brilliant! Mein Chef sagte mir, dass wir einen Kunden hatten, der verärgert war, weil er der Meinung war, dass seine Enterprise-Lizenz nicht mehr als die Standard-Lizenz bietet. Jetzt haben wir diese Funktion in unser Programm aufgenommen, und nur weil sie langsamer ausgeführt wird, denkt er, dass seine Software VIEL mehr Arbeit leistet!!!

    – Phil

    7. November 2014 um 4:04 Uhr

  • Ich denke nicht, dass es fair ist zu sagen, dass es schneller ist als die Verwendung von Division oder Modul. Der C-Standard sagt nichts über die Leistung von Operatoren aus, und jeder anständige Compiler wird für beides schnellen Code produzieren. Ich persönlich würde die Redewendung wählen, die meine Absicht zum Ausdruck bringt, und % scheint hier angemessener zu sein

    – Chris Jung

    2. Oktober 2008 um 5:06 Uhr

  • Ich mag (x & 1) lieber, weil es prüft, ob die Zahl gerade ist, genauso wie die Leute es tun: prüfen, ob die letzte Ziffer gerade oder ungerade ist. Meiner Meinung nach kommuniziert es seine Absicht mehr als die Modulo-Methode. (Nicht, dass es viel ausmacht.)

    – Paige Ruten

    2. Oktober 2008 um 5:22 Uhr

  • Du hast Recht, ich denke, es ist subjektiv. Obwohl die übliche Definition von “gerade” “ganzzahlig ist, die durch 2 teilbar ist”, nicht “ganzzahlig, die auf 0, 2, 4, 6 oder 8 endet”. 🙂

    – Chris Jung

    2. Oktober 2008 um 6:04 Uhr

  • @TraumaPony – für ANSI-Standard C und frühes Java, hängt vom Computersystem ab. Es ist nicht angegeben, welche Darstellung für vorzeichenbehaftete Zahlen verwendet wird – 2er-Komplement, 1er-Komplement, Gray-Codierung usw. Aber Modulus ist immer Modulus

    – Aaron

    2. Oktober 2008 um 9:07 Uhr

  • Funktioniert nicht universell für negative Zahlen. Siehe Überprüfen Sie diese Antwort für weitere Details: stackoverflow.com/questions/160930/… für Details.

    – Andrew Edgecombe

    2. Oktober 2008 um 10:14 Uhr

Benutzeravatar von Sklivvz
Sklivvz

[Joke mode=”on”]

public enum Evenness
{
  Unknown = 0,
  Even = 1,
  Odd = 2
}

public static Evenness AnalyzeEvenness(object o)
{

  if (o == null)
    return Evenness.Unknown;

  string foo = o.ToString();

  if (String.IsNullOrEmpty(foo))
    return Evenness.Unknown;

  char bar = foo[foo.Length - 1];

  switch (bar)
  {
     case '0':
     case '2':
     case '4':
     case '6':
     case '8':
       return Evenness.Even;
     case '1':
     case '3':
     case '5':
     case '7':
     case '9':
       return Evenness.Odd;
     default:
       return Evenness.Unknown;
  }
}

[Joke mode=”off”]

BEARBEITEN: Verwirrende Werte zur Aufzählung hinzugefügt.

  • Wow … das ist verrückter als die Lösung von SCdF! Hut ab! Keine positive Bewertung … kann dies nicht empfehlen. Aber danke für den Witz!

    – Wes P

    2. Oktober 2008 um 12:19 Uhr

  • Der Vorteil dieses Ansatzes ist, dass er mit mehr als nur Zahlen funktioniert. Auch wenn Sie diese Zeile ersetzen: char bar = foo[foo.Length – 1]; damit: double bar = Char.GetNumericValue(foo[foo.Length – 1]); Dann funktioniert es mit jedem Zahlensystem.

    – Jeffrey L Whitledge

    2. Oktober 2008 um 15:27 Uhr

  • Fehlerbericht: 14.65 wird als seltsam gemeldet, obwohl es unbekannt sein sollte.

    – Die SoftwareJedi

    22. Oktober 2008 um 14:55 Uhr

  • Software Jedi, es ist ein “Feature”. 😉

    – Sklivvz

    23. Oktober 2008 um 13:01 Uhr

  • TheSoftwareJedi: 14,65 ist eine der merkwürdigsten ganzen Zahlen, die ich je gesehen habe.

    – Bruce Aldermann

    19. November 2008 um 21:44 Uhr

Benutzeravatar der Community
Gemeinschaft

Als Antwort auf ffpf – ich hatte vor Jahren genau das gleiche Argument mit einem Kollegen, und die Antwort lautet neines funktioniert nicht mit negativen Zahlen.

Der C-Standard schreibt vor, dass negative Zahlen auf 3 Arten dargestellt werden können:

  • 2er Komplement
  • 1er-Komplement
  • Vorzeichen und Größe

Überprüfung so:

isEven = (x & 1);

funktioniert für das 2er-Komplement und die Vorzeichen- und Betragsdarstellung, aber nicht für das 1er-Komplement.

Ich glaube jedoch, dass Folgendes für alle Fälle funktioniert:

isEven = (x & 1) ^ ((-1 & 1) | ((x < 0) ? 0 : 1)));

Danke an ffpf für den Hinweis, dass das Textfeld nach meinem Kleiner-als-Zeichen alles gefressen hat!

  • Wow … das ist verrückter als die Lösung von SCdF! Hut ab! Keine positive Bewertung … kann dies nicht empfehlen. Aber danke für den Witz!

    – Wes P

    2. Oktober 2008 um 12:19 Uhr

  • Der Vorteil dieses Ansatzes ist, dass er mit mehr als nur Zahlen funktioniert. Auch wenn Sie diese Zeile ersetzen: char bar = foo[foo.Length – 1]; damit: double bar = Char.GetNumericValue(foo[foo.Length – 1]); Dann funktioniert es mit jedem Zahlensystem.

    – Jeffrey L Whitledge

    2. Oktober 2008 um 15:27 Uhr

  • Fehlerbericht: 14.65 wird als seltsam gemeldet, obwohl es unbekannt sein sollte.

    – Die SoftwareJedi

    22. Oktober 2008 um 14:55 Uhr

  • Software Jedi, es ist ein “Feature”. 😉

    – Sklivvz

    23. Oktober 2008 um 13:01 Uhr

  • TheSoftwareJedi: 14,65 ist eine der merkwürdigsten ganzen Zahlen, die ich je gesehen habe.

    – Bruce Aldermann

    19. November 2008 um 21:44 Uhr

Benutzeravatar von fortran
Fortran

Ein schönes ist:

/*forward declaration, C compiles in one pass*/
bool isOdd(unsigned int n);

bool isEven(unsigned int n)
{
  if (n == 0) 
    return true ;  // I know 0 is even
  else
    return isOdd(n-1) ; // n is even if n-1 is odd
}

bool isOdd(unsigned int n)
{
  if (n == 0)
    return false ;
  else
    return isEven(n-1) ; // n is odd if n-1 is even
}

Beachten Sie, dass diese Methode eine Schwanzrekursion mit zwei Funktionen verwendet. Es kann effizient implementiert werden (in eine while/until-Schleife umgewandelt werden), wenn Ihr Compiler Tail-Rekursion wie ein Scheme-Compiler unterstützt. In diesem Fall sollte der Stack nicht überlaufen!

  • Dies handhabt isOdd(0) nicht gut.

    – Steve McLeod

    2. Oktober 2008 um 11:43 Uhr

  • Ich denke, Sie haben eine Endlosschleife (mit Schwanzrekursion) oder einen Stapelüberlauf (ohne Schwanzrekursion) für isOdd() mit beliebigen geraden Werten oder isEven() mit beliebigen ungeraden Werten. Es endet nur mit true. Es ist wieder das Halteproblem.

    – Jeffrey L Whitledge

    2. Oktober 2008 um 15:31 Uhr

  • Oh, klar, korrigiere es ohne Kommentar und lass mich wie einen Idioten dastehen. Das ist gut.

    – Jeffrey L Whitledge

    3. Oktober 2008 um 11:25 Uhr

  • Jetzt haben Sie einen Kompilierungsfehler: In isEven geben nicht alle Codepfade einen Wert zurück. Nein, ich habe diesen Code nicht wirklich ausprobiert, es ist der Compiler in meinem Kopf, der sich beschwert.

    – Jeffrey L Whitledge

    3. Oktober 2008 um 11:28 Uhr

  • Kompilierungsfehler: Nicht alle Pfade geben einen Wert zurück, um Sie mit Fehlerkommentaren zu Ihrem Beispielcode zu bombardieren, aber was passiert, wenn Sie isEven(5) aufrufen

    – Kevin

    22. Oktober 2008 um 15:02 Uhr

1425580cookie-checkWie überprüfe ich, ob eine ganze Zahl gerade oder ungerade ist? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy