2010-12-05 8 views
15

So, wie man eine Funktion schafft, um am nächsten bis 9 9+ 1 am nächsten bis zu gegebenem int zurückzugehen, keinen Rest zu hinterlassen, wenn durch 2 int geteilt?Wie findet man die nächste gerade Zahl für gegebenes int? (gegeben 11 zurück 12)

+10

Dieses Problem nicht ist eindeutig angegeben. 10 ist so nahe wie 11 als 12 ist. Welchen willst du?Und was ist mit negativen Zahlen? Und ist das Eingabe-Integral oder Gleitkomma? –

+0

@David: Die Eingabe ist eindeutig ganzzahlig, aber +1 für den Rest Ihres Kommentars – Cameron

+0

Ich kann nicht glauben, dass es alle nachgewählten Antworten auf eine Frage gibt, die keine Antwort hat! –

Antwort

14

"Nearest" ist mehrdeutig, wenn eine Ganzzahl angegeben wird. Nimm zum Beispiel 9: Sowohl 8 als auch 10 sind gerade und sind gleich daneben. Wenn Sie wollen immer gehen, dann so etwas wie ...

int nearestEvenInt(int to) 
{ 
    return (to % 2 == 0) ? to : (to + 1); 
} 
+0

Fehler C2143 passiert ... – Rella

+15

"Fehler C2143 passiert ..." ... * das * sollte eingeschaltet sein ein T-Shirt. –

+0

Bevor Sie diesen Code schreiben, sollten Sie sagen: "Ich glaube, dass der Optimierer meines Compilers Division und Verzweigung entfernen wird" – Abyx

11

number % 2 == 0?number:number+1

Ein anderer Weg ist (number>>1)<<1 aber ich bin nicht sicher Negative/little/big-endians.

+0

'(Nummer >> 1) << 1' hat UB für negative Werte. ('>>' ist nur implementation-defined, aber '<<' ist undefined; es ist ein arithmetischer Überlauf) –

4

if (x %2 == 0) return x; else return x+1;?

39

zur nächsten int Zur Abrundung:

number+=(number & 1) 
+1

Horray für den kleinen Spaß! – GWW

+7

+1 für Cleverness, -1 für Lesbarkeit ;-) – Cameron

+6

+1 für die Verwendung von Modulo zur Überprüfung, ob eine Zahl gerade ist. – GolezTrol

31

Abrunden sogar

x & ~1 

Runde bis zu sogar

(x + 1) & ~1 
+3

(Hinweis: Im Gegensatz zu den meisten Antworten hier, dies rundet anstelle von oben) –

+0

@Michael Mrozek Vielen Dank für Ihre Nachricht – Abyx

+0

Klar, effizient, prägnant und erschöpfend. Dies ist definitiv die beste Antwort, da das OP nicht oben oder unten spezifiziert wurde. – Tim

8

Die Art, wie ich normalerweise lieber (number+1) & ~1 ist, aber Nicht jeder erkennt das Idiom, also müssen Sie vielleicht Ihr Audi betrachten enheit. Wenn es für negative Ganzzahlen arbeiten soll, dann erkennen Nicht-Zweierkomplement-Implementierungen von C und C++ das Idiom nicht (es wird ungerade negative Zahlen nach unten anstatt nach oben auf negative Vorzeichen- + Betragszahlen runden.) , und negative gerade Zahlen ungerade auf Einsen ergänzen, so dass es nicht vollständig portierbar ist, wenn negative Eingabe erlaubt ist.

Die tragbare Antwort ist (number % 2 == 0) ? number : number+1;, und lassen Sie den Compiler über Optimierung sorgen.

Beachten Sie auch, dass Sie nicht definiert haben, was das Ergebnis für INT_MAX sein soll, das ist ungerade, aber für die gibt es keinen größeren sogar int Wert.

+0

Eine weitere "portable" Möglichkeit ist 'number + (number% 2)', die in C99 positive auf positive und negative Unendlichkeit runden wird. – caf

+0

Wenn Sie von 0 weggehen möchten, ist die Antwort von Caf am besten. Aber wenn du zusammenrunden willst, musst du "&" oder einige fiese Bedingungen verwenden. –

3

Da die meisten der hier Antworten sind entweder nonportable oder haben überschüssige conditionals, hier ist die schnelle und tragbare Antwort:

number += (int)((unsigned)number & 1) 

Der Fall unsigned stellt sicher, dass bitweise und definiert ist, wie erwartet, und die Besetzung zurück zu int (was wohldefiniert ist, da beide möglichen Werte der bitweisen und Operation, Null oder Eins, passen in int) verhindert, number auf unsigned heraufgestuft werden, was dann zu implementierungsdefiniertem Verhalten führen würde, wenn es zurück in int konvertiert wird um das Ergebnis number zuzuweisen.

1

weiß, dass ich die OP für int gefragt, aber hier ist eine Antwort für Schwimmer zu:

number = Math.round(number * 0.5f) * 2; //Closest (up for middle) 
number = Math.ceil(number * 0.5f) * 2; //Always Up 
number = Math.floor(number * 0.5f) * 2; //Always Down 
2

ein wenig zu spät zur Party, aber das ist eine saubere Lösung

n += (n % 2); 
Verwandte Themen