2010-08-05 6 views
0

Je le code suivant:Comportement de mod étrange dans Obj. C

NSInteger index1 = (stop.timeIndex - 1); //This will be -1 
index1 = index1 % [stop.schedule count]; // [stop.schedule count] = 33 

J'ai donc l'expression -1% 33. Cela devrait me donner 32, mais est plutôt me donner 3 ... Je l'ai vérifié deux fois les valeurs de la débogueur. Quelqu'un a-t-il une idée?

+0

'%' se comporte différemment de ce que vous attendez pour les entrées négatives dans C et Objective-C - voir cette question SO précédente: http://stackoverflow.com/questions/2430737/modulo-operator-in-objective-c-returns -le-mauvais-résultat –

+0

Probablement doit être fermé comme doublon: http://stackoverflow.com/questions/2430737/modulo-operator-in-objective-c-returns-the-wrong-result –

Répondre

2

C99 dit dans la section 6.5.5 opérateurs multiplicatifs (mine gras):

Le résultat de l'opérateur / est le quotient de la division du premier opérande par le second; le résultat de l'opérateur % est le reste. Dans les deux opérations, si la valeur de le deuxième opérande est zéro, le comportement est indéfini.

Lorsque des entiers sont divisés, le résultat de l'opérateur / est le quotient algébrique avec toute partie fractionnelle mise au rebut. Si le quotient a/b est représentable, l'expression (a/b)*b + a%b doit être égale à a.

Il est dit que % est le reste et n'utilise pas le mot "module" pour le décrire. En fait, le mot "module" n'apparaît qu'à trois endroits dans ma copie de C99, et ceux-ci se rapportent tous à la bibliothèque et non à un opérateur.

Il ne dit rien qui exige que le reste soit positif. Si un reste positif est requis, la réécriture a%b comme (a%b + b) % b fonctionnera pour le signe a et b et donnera une réponse positive au détriment d'une addition et division supplémentaire. Il peut être moins cher de le calculer en m=a%b; if (m<0) m+=b; selon que les branches manquées ou les divisions supplémentaires sont moins chères dans votre architecture cible.

Édition: Je ne connais rien à Objective-C. Votre question originale a été marquée C et toutes les réponses à ce jour reflètent le langage C, bien que votre exemple semble être le code Objective-C. Je suppose que savoir ce qui est vrai à propos de C est utile.

6

En C, l'opérateur de module ne fonctionne pas avec des nombres négatifs. (Il donne un reste, plutôt que de faire de l'arithmétique modulaire comme son nom l'indique.)

1

Les résultats de l'utilisation de l'opérateur mod sur des nombres négatifs sont souvent inattendus. Par exemple, ceci:

#include <stdio.h> 

int main() { 
    int n = -1 % 33; 
    printf("%d\n", n); 
} 

produit -1 avec GCC, mais je ne vois pas pourquoi vous attendez l'expression d'évaluer à 32 - il va. Il est généralement préférable de ne pas effectuer de telles opérations, en particulier si vous souhaitez que votre code soit portable.

+0

Je compile en utilisant LLVM, ce qui explique probablement la différence, mais 32 est une solution mathématique correcte; c'est aussi comment python évalue l'expression. – kodai