10
votes

Retourner zéro pour des entiers négatifs

Un ami vient de lancer un code similaire à celui suivant C # Code: XXX

Cela m'a fait penser. Il existe une façon "différente" de retourner zéro pour des entiers négatifs ou de la valeur positive actuelle? Plus spécifiquement, je cherche des opérations bitwises, si possible.

BTW, je suis au courant de math.max (0, i);


4 commentaires

Comment cela se qualifie comme le golf de code?


Je <0? 0: I - As-tu vraiment attendu quelque chose de plus petit que 7 caractères?


Dites à votre ami de ne pas lancer de code. Cela pourrait frapper quelqu'un dans l'oeil.


+1 Je ne vais plus jamais jeter du code !!


5 Réponses :


3
votes

Réponse courte: Non.

Les opérateurs de bits font quelque chose de très différent, ou plutôt sont utilisés pour différents problèmes.

Si vous connaissez la taille de vos entiers, vous pouvez tester le bit le plus élevé (le plus significatif); Si c'est 1, le nombre est négatif et vous pouvez agir à ce sujet. Mais ce serait un diable de beaucoup plus de travail que le simple test "<".


1 commentaires

Et je ne serais pas surpris si le compilateur fait déjà cette optimisation.



29
votes

Qu'est-ce qui ne va pas avec math.max code>?

vous peut em> faire l'équivalent sans succursale à l'aide des opérations bitwises: P>

r = (y & -(0 < y)); // == max(0, y)


7 commentaires

Généralement (x


Ce n'est que vrai sur certaines plates-formes. La plupart ont une instruction de comparaison du résultat qui peut être déplacé ou décalé dans un registre général.


@Aaron, pas vrai X86 est un ensemble d'instructions riches très .


VRAI - Je viens de l'essayer et MSDev a utilisé l'instruction "SETG" - donc aucune branche nécessaire.


Si le JIT de Mme est assez intelligent, Math.Max ​​devrait déjà faire cela.


Alors que ce genre de piratage de terrain est un peu gentil, il ne compilera pas comme celui-ci en C #, car la langue ne permet pas d'opérations arithmétiques sur les booléens, il faudrait donc être r = (Y & - (0


@Grizzy true qui générera une succursale en code CIL. Pour le boîtier max (0, y) , vous pouvez remplacer l'expression C - (0 avec l'expression C # - (int) (int) ( ((UINT) Y >> (8 * Tailleof (int) - 1)) ^ 1) , qui générerait 5 ou deux instructions CIL et aucune branche. Comme si ce n'était pas assez moche déjà ...



3
votes

Non Bitwise mais différent:

return (int)(i/2f + Math.abs(i)/2f)


1 commentaires

Kinky, mais mon sens de débordement est chatouillant :)



6
votes

Que diriez-vous:

int i = ...;

retour I & ~ (i >> 31);


2 commentaires

Bon point - Je l'ai modifié - il devrait maintenant fonctionner pour tous les cas.


Argh la même stratégie mais beaucoup plus propre que la mienne. Je ne savais pas le ~ pour être honnête



4
votes

Le ci-dessous fera l'affaire et le code lit aussi bien qu'il n'a pratiquement pas besoin d'un commentaire;) xxx

à nouveau xxx

et voila zéro pour tous les nombres négatifs et tous les positifs sont laissés inchangés


0 commentaires