42 votes

Comportement bizarre des Modes Objective-C pour les nombres négatifs

J'ai donc pensé que les nombres négatifs, lorsqu'ils sont modélisés, devraient être placés dans un espace positif... Je n'arrive pas à faire cela avec Objective-C

Je m'y attends :

-1 % 3 = 2
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

Mais voici ce qu'il en est

-1 % 3 = -1
 0 % 3 = 0
 1 % 3 = 1
 2 % 3 = 2

Pourquoi en est-il ainsi et existe-t-il une solution de contournement ?

53voto

UncleO Points 4675
result = n % 3;
if( result < 0 ) result += 3;

N'effectuez pas d'opérations de mod supplémentaires comme le suggèrent les autres réponses. Elles sont très coûteuses et inutiles.

14voto

Adam Rosenfield Points 176408

En C et en Objective-C, les opérateurs division et module effectuent une troncature vers zéro. a / b es floor(a / b) si a / b > 0 Sinon, il s'agit de ceiling(a / b) si a / b < 0 . Il arrive toujours que a == (a / b) * b + (a % b) sauf, bien sûr, si b est de 0. En conséquence, positive % positive == positive , positive % negative == positive , negative % positive == negative y negative % negative == negative (vous pouvez calculer la logique pour les 4 cas, même si c'est un peu difficile).

8voto

Peter N Lewis Points 12025

Si n a une portée limitée, vous pouvez obtenir le résultat que vous souhaitez simplement en ajoutant un multiple constant connu de 3 qui est supérieur à la valeur absolue du minimum.

Par exemple, si n est limité à -1000..2000, vous pouvez utiliser l'expression :

result = (n+1002) % 3;

Assurez-vous que la somme du maximum et de votre constante ne déborde pas.

7voto

Arthur Ulfeldt Points 45059

Nous avons un problème de langue :

math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
  • le mathématicien de cette conversation parle de faire des calculs sur une ligne numérique circulaire. Si vous faites une soustraction à partir du bas, vous vous retrouvez en haut.
  • le codeur parle d'un opérateur qui calcule le reste.

Dans ce cas, vous souhaitez utiliser l'opérateur mod du mathématicien et disposez de la fonction de reste. Vous pouvez convertir l'opérateur de reste en opérateur mod du mathématicien en vérifiant si vous êtes tombé du bas à chaque fois que vous effectuez une soustraction.

4voto

e.James Points 51680

J'aurais également attendu un nombre positif, mais j'ai trouvé ceci, tiré de la norme ISO/IEC 14882:2003 : Langages de programmation -- C++, 5.6.4 (trouvée dans le document Article de Wikipédia sur l'opération modulus ) :

L'opérateur binaire % donne le reste de la division de la première expression par la seconde. .... Si les deux opérandes sont non négatifs, le reste est non négatif ; dans le cas contraire, le signe du reste est défini par l'implémentation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X