2010-08-18 4 views
20

if counter % 2 == 1 J'essaye de décoder cette ligne - c'est un projet de Rails et j'essaye de deviner ce que le % fait dans cette instruction si.Que fait l'opérateur% dans Ruby dans N% 2?

+1

Odeur de quelque chose pour vérifier les valeurs impaires du compteur. –

+1

Un petit casse-tête pour vous: en C#, le test que vous faites ne * vérifie * pas * de manière fiable si le compteur est impair. Est-ce que quelqu'un voit pourquoi?(Indice: dans Ruby, quelle est la différence entre les méthodes restantes et modulo sur les nombres numériques?) –

+0

Également utilisable pour les substitutions de chaînes - http://ruby-doc.org/core/classes/String.html#M000770 –

Répondre

40

% est l'opérateur modulo. Le résultat de counter % 2 est le reste de counter/2.

n % 2 est souvent un bon moyen de déterminer si un nombre n est pair ou impair. Si n % 2 == 0, le nombre est pair (car aucun reste signifie que le nombre est divisible par 2); si n % 2 == 1, le nombre est impair.

+0

Vous * certain * à propos de cette dernière revendication? C'est vrai dans Ruby mais pas dans d'autres langues! –

+0

@Eric ce qui n'est pas vrai? Je n'ai pas dit que c'est la seule ou la meilleure façon de déterminer si un nombre est pair ou impair ... –

+0

Ce que je voulais dire, c'est que le test n% 2 == 1 * ne détermine pas si un nombre est impair * dans de nombreux cas langues. En C# par exemple, il détermine si un nombre est * à la fois positif et impair *, ce qui est différent. –

2

C'est l'opérateur modulo. Il donne le reste lorsque le compteur est divisé par 2.

For example: 
3 % 2 == 1 
2 % 2 == 0 
0

Il est l'opérateur modulo, ce qui est une façon élégante de dire qu'il est l'opérateur reste. Par conséquent, si vous divisez un nombre par deux et que le nombre entier de ce nombre est égal à un, vous savez que le nombre était impair. Votre exemple vérifie les nombres impairs.

Souvent, cela est fait pour mettre en surbrillance des rangées de nombres impairs avec une couleur d'arrière-plan différente, ce qui facilite la lecture de grandes listes de données.

0

Pour donner quelques façons de le dire:

  • opérateur Modulo
  • opérateur Reliquat
  • résidus modulaire

Strictement parlant, si a % b = c, c est la constante unique tel que

a == c (mod b) et 0 <= c < b

x == y (mod m) ss x - y = km pour une constante k.

Ceci est équivalent au reste. Par un théorème bien connu, nous avons que a = bk + c pour une constante k, où c est le reste, ce qui nous donne a - c = bk, ce qui implique évidemment a == c (mod b).

(Y at-il un moyen d'utiliser LaTeX Stackoverflow?)

0

Ceci est une question fondamentale. % est le modulo operateur if counter % 2 == 1 résultats à true pour chaque nombre impair et à false pour chaque nombre pair.

Si vous êtes en train d'apprendre le rubis, vous devriez apprendre à utiliser irb, là vous pouvez essayer des choses et peut-être répondre à la question vous-même.

essayer d'entrer dans

100.times{|i| puts "#{i} % 2 == 1 #=> #{i % 2 == 1}"} 

dans votre console irb et irb voir la sortie, qu'il doit être clair que % fait.

Et vous devriez vraiment jeter un oeil au niveau des rails documentation api (1.9, 1.8.7, 1.8.7), vous y avez trouvé la réponse à deux votre question % (Fixnum) avec un autre lien vers une description détaillée de divmod (Numeric):

Renvoie un tableau contenant le quotient et le module obtenus en divisant num par aNumeric. > Si q, r = x.divmod (y), alors

q = floor(float(x)/float(y)) 
x = q*y + r 

Le quotient est arrondi vers l'infini négatif, comme le montre le tableau suivant:

a | b | a.divmod(b) | a/b | a.modulo(b) | a.remainder(b) 
------+-----+---------------+---------+-------------+--------------- 
13 | 4 | 3, 1  | 3  | 1  |  1 
------+-----+---------------+---------+-------------+--------------- 
13 | -4 | -4, -3  | -3  | -3  |  1 
------+-----+---------------+---------+-------------+--------------- 
-13 | 4 | -4, 3  | -4  | 3  | -1 
------+-----+---------------+---------+-------------+--------------- 
-13 | -4 | 3, -1  | 3  | -1  | -1 
------+-----+---------------+---------+-------------+--------------- 
11.5 | 4 | 2, 3.5 | 2.875 | 3.5  |  3.5 
------+-----+---------------+---------+-------------+--------------- 
11.5 | -4 | -3, -0.5 | -2.875 | -0.5  |  3.5 
------+-----+---------------+---------+-------------+--------------- 
-11.5 | 4 | -3, 0.5 | -2.875 | 0.5  | -3.5 
------+-----+---------------+---------+-------------+--------------- 
-11.5 | -4 | 2 -3.5 | 2.875 | -3.5  | -3.5 

Exemples

11.divmod(3)   #=> [3, 2] 
11.divmod(-3)  #=> [-4, -1] 
11.divmod(3.5)  #=> [3, 0.5] 
(-11).divmod(3.5) #=> [-4, 3.0] 
(11.5).divmod(3.5) #=> [3, 1.0] 
1

Peu importe comment cela fonctionne, l'opérateur modulo n'est probablement pas le meilleur code pour ce but (même si nous ne recevons pas beaucoup de contexte). Comme Jörg mentionné dans un commentaire, l'expression if counter.odd? est probablement l'intention, et est plus lisible. S'il s'agit d'un code de vue et qu'il est utilisé pour déterminer (par exemple) l'alternance des couleurs des lignes, vous pouvez vous en passer entièrement en utilisant l'assistant Rails intégré cycle(). Par exemple, vous pouvez utiliser cycle('odd','even') comme nom de classe pour une ligne de table, en éliminant le compteur et la logique if/then environnante.

Autre idée: si cela se trouve dans un bloc each, vous pouvez utiliser each_with_index et éliminer la variable de compteur étrangère.

Mon refactoring 0,02 $.

0

Gardez également à l'esprit que la définition de Ruby de l'opérateur modulo (%) diffère de celle de C et Java. Dans Ruby, -7%3 est 2. En C et Java, le résultat est -1 à la place. Dans Ruby, le signe du résultat (pour l'opérateur %) est toujours le même que le signe du deuxième opérande.

37

En réponse à la question «Que fait ou veut dire le symbole% dans Ruby? Il est:

1) Le modulo opérateur binaire (comme cela a été mentionné)

17 % 10 #=> 7 

2) La chaîne de remplacement délimiteur jeton

%Q{hello world} #=> "hello world" 
%Q(hello world) #=> "hello world" 
%Q[hello world] #=> "hello world" 
%Q!hello world! #=> "hello world" 
# i.e. choose your own bracket pair 
%q(hello world) #=> 'hello world' 
%x(pwd)   #=> `pwd` 
%r(.*)   #=> /.*/ 

3) L'opérateur de format de chaîne (abréviation de noyau :: sprintf)

"05d" % 123 #=> "00123" 
+8

+1 pour être le seul à mentionner l'opérateur de format de chaîne. C'était la réponse particulière que je cherchais. – nocash