Testen, ob ein Wert ungerade oder gerade ist


173

Ich habe beschlossen, einfache isEven- und isOdd- Funktionen mit einem sehr einfachen Algorithmus zu erstellen :

function isEven(n) {
  n = Number(n);
  return n === 0 || !!(n && !(n%2));
}

function isOdd(n) {
  return isEven(Number(n) + 1);
}

Das ist in Ordnung, wenn n bestimmte Parameter enthält, schlägt jedoch in vielen Szenarien fehl. Deshalb habe ich mich vorgenommen, robuste Funktionen zu erstellen, die für so viele Szenarien wie möglich korrekte Ergebnisse liefern, sodass nur Ganzzahlen innerhalb der Grenzen von Javascript-Zahlen getestet werden und alles andere false zurückgibt (einschließlich + und - unendlich). Beachten Sie, dass Null gerade ist.

// Returns true if:
//
//    n is an integer that is evenly divisible by 2
//
// Zero (+/-0) is even
// Returns false if n is not an integer, not even or NaN
// Guard against empty string

(function (global) {

  function basicTests(n) {

    // Deal with empty string
    if (n === '') 
      return false;

    // Convert n to Number (may set to NaN)
    n = Number(n);

    // Deal with NaN
    if (isNaN(n)) 
      return false;

    // Deal with infinity - 
    if (n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY)
      return false;

    // Return n as a number
    return n;
  }

  function isEven(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Convert to Number and proceed
    n = Number(n);

    // Return true/false
    return n === 0 || !!(n && !(n%2));
  }
  global.isEven = isEven;

  // Returns true if n is an integer and (n+1) is even
  // Returns false if n is not an integer or (n+1) is not even
  // Empty string evaluates to zero so returns false (zero is even)
  function isOdd(n) {

    // Do basic tests
    if (basicTests(n) === false)
      return false;

    // Return true/false
    return n === 0 || !!(n && (n%2));
  }
  global.isOdd = isOdd;

}(this));

Kann jemand irgendwelche Probleme mit den oben genannten sehen? Gibt es eine bessere (dh genauere, schnellere oder präzisere Version, ohne verschleiert zu werden) Version?

Es gibt verschiedene Beiträge zu anderen Sprachen, aber ich kann anscheinend keine endgültige Version für ECMAScript finden.


Antworten:


368

Modul verwenden:

function isEven(n) {
   return n % 2 == 0;
}

function isOdd(n) {
   return Math.abs(n % 2) == 1;
}

Sie können überprüfen, ob ein beliebiger Wert in Javascript zu einer Zahl gezwungen werden kann mit:

Number.isFinite(parseFloat(n))

Diese Überprüfung sollte vorzugsweise außerhalb der Funktionen isEvenund durchgeführt isOddwerden, damit Sie die Fehlerbehandlung nicht in beiden Funktionen duplizieren müssen.


@Steve Ja, aber JS hat einige spezielle Probleme, wenn valuees sich nicht um eine Nummer handelt oder wenn es sich um eine Nummer handelt. Bsp .: 0.1%2, NaN%2, []%2etc. Was Sie in der Antwort schrieb, er weiß es schon.
Alin Purcaru

1
0.1und NaNarbeiten gut mit der obigen Funktion. Leeres Array ist ein bisschen schmerzhaft, da es 0 entspricht ...
Steve Mayne

4
@Alin - Ich habe eine numerische Prüfung hinzugefügt. Ich bin nicht sicher, ob ich das Szenario verstehe, in dem eine arithmetische Funktion explizit andere Datentypen verarbeiten soll, aber wenn das OP dies wünscht ...
Steve Mayne

2
Was ist mit dem Wechsel return n == parseInt(n);zu return n === parseInt(n);?
JiminP

2
Ich glaube, ich habe irgendwo gelesen, was Sie überprüfen sollten, n % 2 !== 0wenn Sie nach ungeraden Zahlen suchen, da es je nach Sprache nicht unbedingt 1 ist. EDIT: Ah, dafür ist der .absAnruf da. Egal Dann.
ptf

78

Ich bevorzuge einen kleinen Test:

if(i & 1)
{
    // ODD
}
else
{
    // EVEN
}

Dies testet, ob das erste Bit aktiviert ist, das eine ungerade Zahl anzeigt.


Nur nützlich, wenn Sie wissen, dass ich eine Nummer bin, mit der Sie beginnen. Nicht-Zahlen sollten undefiniert zurückgeben (oder einen Fehler auslösen, aber undefiniert erscheint sinnvoll).
RobG

3
Absolut. Die Verwendung des Moduls für die Basis-2-Mathematik sollte illegal sein;)
aceofspades

4
Ternär: i & 1 == 1 ? console.log("odd") : console.log("even");Auch +1 für die Effizienz auf Bitebene (in JS nicht so weit verbreitet)
Jacksonkr

13
@Jacksonkr Beachten Sie, dass es in JavaScript keine „Effizienz auf Bitebene“ gibt, da alle Zahlen in JavaScript Gleitkommazahlen sind. Wenn Sie einen bitweisen Operator verwenden, müssen Sie ihn zuerst in ein int konvertieren, dann die Operation ausführen und dann wieder in eine Gleitkommazahl konvertieren.
stupsen

1
@poke Richtig, sie sind vom Typ Number, aber es ist schön zu wissen, dass stark typisierte Sprachen effizient sind.
Robert Brisita

8

Wie wäre es mit folgendem? Ich habe dies nur im IE getestet, aber es war ziemlich glücklich, Zeichenfolgen zu verarbeiten, die Zahlen beliebiger Länge darstellen, tatsächliche Zahlen, die Ganzzahlen oder Gleitkommazahlen sind, und beide Funktionen haben false zurückgegeben, wenn ein Boolescher Wert, ein undefinierter Wert, ein Array oder ein Objekt übergeben wurde. (Es liegt an Ihnen, ob Sie führende oder nachfolgende Leerzeichen ignorieren möchten, wenn eine Zeichenfolge übergeben wird. Ich habe angenommen, dass sie nicht ignoriert werden und beide Funktionen false zurückgeben.)

function isEven(n) {
   return /^-?\d*[02468]$/.test(n);
}

function isOdd(n) {
   return /^-?\d*[13579]$/.test(n);
}

2
Für meine Implementierung gibt isEven (2.122e3) true zurück, isEven ("2.122e3") jedoch false. Umgekehrt schlägt mein isEven () für wirklich große Zahlen fehl, weil JS sie beim Konvertieren in einen String für den Regex-Test in das Exponentenformat versetzt. Naja.
nnnnnn

@MartijnScheffer - Sie können mir gerne die Rechnung für all den zusätzlichen Speicher senden, den Sie kaufen müssen. Beachten Sie, dass die Frage Konvertierungen von anderen Typen in Zahlen enthielt, und ich schlage hier eindeutig vor, eine einfache einzeilige Funktion zu haben, die Zahlen und Zeichenfolgen verarbeitet. Natürlich werden nach meinem eigenen Kommentar nicht alle möglichen Fälle behandelt, aber es kann dennoch nützlich sein - Regex ist der einfachste Weg, vom Benutzer eingegebene Daten zu validieren, bei denen es sich zunächst um eine Zeichenfolge handelt.
nnnnnn

Habe ich hier einen Kommentar gepostet? Ich sehe es nicht, aber ich kann, wenn Sie eine wollen! Dies ist KEINE korrekte Lösung, dies ist hunderte Male langsamer, und wir sprechen von Zahlen, nicht von Zeichenfolgen, wenn Sie überprüfen möchten, ob eine Zeichenfolge gültig ist Zahl und eine Ganzzahl, die separat behandelt werden kann.
Martijn Scheffer

@MartijnScheffer - Ja, es gab einen Kommentar von Ihnen, scheint seit meiner Antwort irgendwann gelöscht worden zu sein. Beachten Sie, dass es bei der Frage nicht nur um Zahlen ging, sondern dass der OP-Code auch Konvertierungen von anderen Typen enthielt. Trotzdem danke für dein Feedback.
nnnnnn

7

Hinweis: Es gibt auch negative Zahlen.

function isOddInteger(n)
{
   return isInteger(n) && (n % 2 !== 0);
}

wo

function isInteger(n)
{
   return n === parseInt(n, 10);
}

1
Benötigt parseInt hier keinen Radix?
Blablabla

@blablabla Ja, nicht alle Implementierungen setzen Radix = 10 voraus.
Rodrigo

Gute Angabe negativer Werte. Die Antwort von Robert Brisita (die später hinzugefügt wurde) deckt dies ebenfalls ab.
Jacksonkr

4

Warum nicht einfach so machen:

    function oddOrEven(num){
        if(num % 2 == 0)
            return "even";
        return "odd";
    }
    oddOrEven(num);

Oder sogar function isEven(num) { return num % 2 == 0}
Chiapa

3
oder mit ES6:const oddOrEven = num => num % 2 === 0 ? 'even' : 'odd'
enguerran


1
var isEven = function(number) {
    // Your code goes here!
    if (number % 2 == 0){
       return(true);
    }
    else{
       return(false);    
    }
};

2
Das if ( <expression> ) return true else return falseParadigma kann immer vereinfacht werden return ( <expression> )(da der Ausdruck in einem if bereits immer ein boolescher ist).
Gerold Broser

zu sagen, dass return keine Funktion ist, ist wie zu sagen, wenn keine Funktion ist, ist es vollkommen gültig, Klammern zu verwenden, wenn ein Wert zurückgegeben wird (auch wenn sie hier nicht nützlich sind)
Martijn Scheffer

1

Eine einfache Modifikation / Verbesserung der Antwort von Steve Mayne!

function isEvenOrOdd(n){
    if(n === parseFloat(n)){
        return isNumber(n) && (n % 2 == 0);
    }
    return false;
}

Hinweis: Gibt bei Ungültigkeit false zurück!


1

Wir brauchen dafür nur eine Codezeile!

Hier eine neuere und alternative Möglichkeit, dies mithilfe der neuen ES6- Syntax für JS-Funktionen und der einzeiligen Syntax für den if-elseAnweisungsaufruf zu tun :

const isEven = num => ((num % 2) == 0) ? true : false;

alert(isEven(8));  //true
alert(isEven(9));  //false
alert(isEven(-8)); //true

1
Welches ist kürzer als let isEven = num => num % 2 === 0. :-) Aber es ist wirklich nicht anders als viele andere Antworten hier.
RobG

1

Ein paar

x % 2 == 0; // Check if even

!(x & 1); // bitmask the value with 1 then invert.

((x >> 1) << 1) == x; // divide value by 2 then multiply again and check against original value

~x&1; // flip the bits and bitmask

0

Anders:

var isEven = function(number) {
  // Your code goes here!
  if (((number/2) - Math.floor(number/2)) === 0) {return true;} else {return false;};
};

isEven(69)

0

Ansonsten mit Strings, weil warum nicht

function isEven(__num){
    return String(__num/2).indexOf('.') === -1;
}

0
if (testNum == 0);
else if (testNum % 2  == 0);
else if ((testNum % 2) != 0 );

Ohne Erklärung hat Ihr Beitrag nicht viel Wert. Es werden auch Informationen wiederholt, die bereits in der Diskussion vorgestellt wurden.
Cindy Meister

Danke Cindy! Nur eine Lösung anbieten!
Lindsay

Aber ... das eigentlich nicht tut nichts. Sollte es nicht etwas zurückgeben?
nnnnnn

0

Vielleicht das? if (ourNumber% 2! == 0)


2
Während dieses Code-Snippet die Frage lösen kann, hilft eine Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage für Leser in Zukunft beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen. Bitte versuchen Sie auch, Ihren Code nicht mit erklärenden Kommentaren zu überfüllen. Dies verringert die Lesbarkeit sowohl des Codes als auch der Erklärungen!
Filnor

0
var num = someNumber
    isEven;
parseInt(num/2) === num/2 ? isEven = true : isEven = false;

0

for(var a=0; a<=20;a++){
   if(a%2!==0){
       console.log("Odd number "+a);
   }
}

for(var b=0; b<=20;a++){
    if(b%2===0){
        console.log("Even number "+b);  
    }     
 }


Während dieser Code die Frage lösen kann, einschließlich einer Erklärung, wie und warum dies das Problem löst, würde dies wirklich dazu beitragen, die Qualität Ihres Beitrags zu verbessern, und wahrscheinlich zu mehr Up-Votes führen. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt. Bitte bearbeiten Sie Ihre Antwort, um Erklärungen hinzuzufügen und anzugeben, welche Einschränkungen und Annahmen gelten.
Daniil

-1

Dies funktioniert auch, um zu testen, ob Sie eine ungerade oder eine gerade Zahl haben.

const comapare = x => integer(checkNumber(x));

function checkNumber (x) {
   if (x % 2 == 0) {
       return true;
   } 
   else if (x % 2 != 0) {
       return false;
    }
}

function integer (x) {
   if (x) {
       console.log('even');
   } 
   else {
       console.log('odd');
    }
}

-1

Verwendung des modernen Javascript-Stils:

const NUMBERS = "nul one two three four five six seven ocho nueve".split(" ")

const isOdd  = n=> NUMBERS[n % 10].indexOf("e")!=-1
const isEven = n=> isOdd(+n+1)

isOdd('5'))gibt true zurück. isEven('5')gibt auch true zurück. isOdd(NaN)wirft einen Fehler. :-(
RobG

Behoben isEven('5'). isOdd(NaN)sollte wahrscheinlich einen Fehler auslösen.
Gunn

1
Der Skript-Host sollte den Fehler nicht behandeln, die Funktion sollte. Mir wurde immer gesagt, dass ein Core Dump keine normale Kündigung ist . ;-)
RobG


-2
function isEven(n) {return parseInt(n)%2===0?true:parseInt(n)===0?true:false}

wenn 0 / wollte aber doch

isEven(0) //true
isEven(1) //false
isEven(2) //true
isEven(142856) //true
isEven(142856.142857)//true
isEven(142857.1457)//false

.


Oder return parseInt(n)%2===0?true:parseInt(n)===0. Andererseits ist dies dasselbe wie bei vielen anderen Antworten, die bereits hier vorliegen.
Heretic Monkey

1
Oder return parseInt(n)%2 === 0 || parseInt(n) === 0. Aber warum parseInt ? Das gibt true für Werte wie "32foo" und zurück 12.5, die nicht gerade sind.
RobG

-2
if (i % 2) {
return odd numbers
}

if (i % 2 - 1) {
return even numbers
}

1
Wann wird die Erinnerung daran, eine Zahl durch 2 zu teilen, 2 sein?
user85421

Hm, ja du hast recht. Ich vermisse es,% 2 == 2 zu schreiben. Mein schlechtes.
Dejan Markovic
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.