2011-09-12 12 views
9

Busco una explicación sencilla de cómo funciona módulo de operando de Ruby y por qué, en Rubyoperando el módulo de rubí en comparación con php

puts 4 % 3 # 1 
puts -4 % 3 # 2 <--why? 
puts -4 % -3 # -1 

pero en PHP:

<?php 

echo 4 % 3; # 1 
echo -4 % 3; # -1 
echo -4 % -3; # -1 

parece a mí como -4% 3 es actalmente 8% 3 (8 es la diferencia entre 4 y -4).

+3

El comportamiento de X% de Y, donde X o Y son negativas es una opción de diseño (que puede ser "indefinido comportamiento"). Nada más y nada menos. Esta sección sobre [división entera] (http://www.davidflanagan.com/2006/06/integer-division-and-negative-numbers.html) y los comentarios pueden llevar a más ideas. IIRC la razón de este "comportamiento extraño" en Ruby se discute en el ML. –

+1

Si Ruby hace las cosas de una manera, y PHP hace las cosas otra, ¡supongamos que Ruby lo está haciendo de la manera correcta! j/k –

Respuesta

15

Ambos pueden considerarse correctos, dependiendo de su definición. Si a % n == r, entonces se debe considerar que:

a == q*n + r 

donde q == a/n.

Si r es positivo o negativo viene determinado por el valor de q. Así que en su ejemplo, cualquiera de:

-4 == -1*3 + (-1) // PHP 
-4 == -2*3 + 2  // Ruby 

para decirlo de otra manera, la definición de % depende de la definición de /.

Véase también la tabla aquí: http://en.wikipedia.org/wiki/Modulus_operator#Remainder_calculation_for_the_modulo_operation. Verás que esto varía sustancialmente entre varios lenguajes de programación.

+1

Ah, esto hizo que haga clic para mí: "la definición de% depende de la definición de /". ¡Gracias! – typeoneerror

-1

Según Wolfram Alpha, 2 es correcto.

editar: Parece que debería estar preguntando por qué PHP funciona de esa manera?

edit2: PHP lo define como el resto de devision A/B. Si lo considera un error, una forma incorrecta o diferente de hacer las cosas, depende de usted, supongo. Personalmente, voy por los primeros 2.

+1

Pregunto acerca de la diferencia, no cuál es la correcta, así que supongo que estoy preguntando por qué PHP funciona de esa manera. ¿Alguna idea? – typeoneerror

+3

@Kyle: no es ni un error ni un error. –

6

Here's a snippet sobre el tema de The Ruby Programming Language, por Matz y David Flanagan.

Cuando uno (pero no ambos) de los operandos es negativo, Ruby realiza la división número entero y modulo operaciones de manera diferente que idiomas como C, C++ y Java (pero al igual que los idiomas de Python y Tcl) Considera el cociente -7/3. Ruby redondea hacia el infinito negativo y devuelve -3. C y las lenguas relacionadas redondean hacia cero en su lugar y return -2. En Ruby, -a/b es igual aa/-b pero no es igual a - (a/b).

definición de la operación del módulo de Ruby también difiere de la de C y Java. En Ruby, -7% 3 es 2. En C y Java, el resultado es -1 en su lugar. La magnitud del resultado difiere, porque el cociente difiere. Pero el signo del resultado difiere también. En Ruby, el signo del resultado es siempre el signo del segundo operando. En C y Java, el signo del resultado es siempre el signo del primer operando. (método del resto de Ruby se comporta como el operador de módulo C.)

1

En realidad, se reduce a la aplicación del lenguaje del número entero de fundición/redondeo.Como la ecuación actual es:

a - (n * int(a/n)) 

Es la porción int(a/n) de la ecuación que difiere. Si a == -4 y n == 3, PHP devolverá -1, mientras que Ruby producirá -2. Ahora la ecuación es la siguiente con Ruby:

-4 - (3 * -2) 

y esto en PHP

-4 - (3 * -1)