2010-12-05 42 views
15

donc comment créer une fonction pour renvoyer le plus proche de façon à ce la plus proche à 9 9+ 1 à donné int ne laissant aucun reste quand divisé par 2 int?Comment trouver le nombre pair le plus proche pour un int donné? (Compte tenu de 11 retour 12)

+10

Ce problème n'est pas spécifié de manière unique. 10 est aussi proche de 11 que 12 est. Lequel veut-tu?Et qu'en est-il des nombres négatifs? Et l'entrée est-elle intégrale ou flottante? –

+0

@David: L'entrée est clairement intégrale, mais +1 pour le reste de votre commentaire – Cameron

+0

Je ne peux pas croire qu'il y ait toutes les réponses à une question qui n'a pas de réponse! –

Répondre

14

« le plus proche » est ambigu quand donné un nombre entier. Prenez, disons, 9: les 8 et 10 sont égaux, et sont également proches. Si vous voulez aller toujours, alors quelque chose comme ...

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

erreur C2143 arrive ... – Rella

+15

"erreur C2143 arrive ..." ... * que * devrait être activé un t-shirt. –

+0

Avant d'écrire ce code, vous devriez dire: "Je crois que l'optimiseur de mon compilateur supprimera la division et la dérivation" – Abyx

11

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

Une autre façon est (number>>1)<<1 mais je ne suis pas sûr de négatifs/petits/grands-Boutiens.

+0

'(nombre >> 1) << 1' a UB pour les valeurs négatives. ('>>' est seulement défini par l'implémentation, mais '' '' est non défini, c'est un dépassement arithmétique signé) –

4

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

39

Pour arrondir au plus proche int:

number+=(number & 1) 
+1

Horray pour s'amuser un peu trop! – GWW

+7

+1 pour l'intelligence, -1 pour la lisibilité ;-) – Cameron

+6

+1 pour ne pas utiliser modulo pour vérifier si un nombre est pair. – GolezTrol

31

arrondissez à même

x & ~1 

ronde jusqu'à même

(x + 1) & ~1 
+3

(Note: Contrairement à la plupart des réponses ici, cela arrondit à la baisse) –

+0

@Michael Mrozek merci pour votre note – Abyx

+0

Clair, efficace, concis et exhaustif. C'est certainement la meilleure réponse car l'OP n'a pas spécifié haut ou bas. – Tim

8

La façon dont je préfère normalement est (number+1) & ~1, mais pas tout le monde reconnaît l'idiome, donc vous pourriez avoir à considérer votre audi l'origine. En particulier, s'il est supposé fonctionner avec des entiers négatifs, les implémentations de C et C++ non-two's-complement ne reconnaissent pas l'idiome (il arrondit les nombres négatifs impairs vers le bas au lieu du signe négatif + les nombres de magnitude , et transforme les nombres pairs négatifs en nombre impair), de sorte qu'il n'est pas entièrement portable dans le cas où une entrée négative est autorisée.

La réponse portable est (number % 2 == 0) ? number : number+1;, et que le souci du compilateur sur l'optimisation.

Méfiez-vous également que vous n'avez pas défini ce que le résultat devrait être pour INT_MAX, ce qui est impair mais pour lequel il n'existe pas de valeur int plus grande.

+0

Une autre possibilité "portable" est 'nombre + (nombre% 2)', qui dans C99 arrondira les positifs vers l'infini positif et l'infini négatif. – caf

+0

Si vous voulez arrondir à 0, la réponse de caf est la meilleure. Mais si vous voulez arrondir, vous aurez besoin d'utiliser '&' ou de quelques conditions désagréables. –

3

Comme la plupart des réponses ici sont soit nonportable ou qui ont excès conditionals, voici la réponse rapide et portable:

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

Le cas unsigned assure que bitwise et est défini comme prévu, et la distribution Retour à int (qui est bien défini car les deux valeurs possibles du bit et de l'opération, zéro ou un, entrer dans int) empêchent number d'être promu à unsigned, ce qui entraînerait alors un comportement défini par l'implémentation lorsqu'il est reconverti en int pour affecter le résultat à number.

1

Je sais que le OP demandé int, mais voici une réponse pour les flotteurs trop:

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

Un peu tard pour le parti, mais cela est une solution propre

n += (n % 2);