¿Cuál es exactamente la diferencia entre mod
y rem
en Haskell?
Ambos parecen dar los mismos resultados.
*Main> mod 2 3
2
*Main> rem 2 3
2
*Main> mod 10 5
0
*Main> rem 10 5
0
*Main> mod 1 0
*** Exception: divide by zero
*Main> rem 1 0
*** Exception: divide by zero
*Main> mod 1 (-1)
0
*Main> rem 1 (-1)
0
mod
ulus ==rem
ainder.div
yquot
Respuestas:
No son lo mismo cuando el segundo argumento es negativo:
fuente
rem
ymod
en Clojure, y esta fue la respuesta.rem
es el más rápido.Sí, esas funciones actúan de manera diferente. Como se define en la documentación oficial :
quot
es la división entera truncada hacia cerorem
es el resto entero, satisfactorio:div
es la división entera truncada hacia el infinito negativomod
es un módulo entero que satisface:Realmente puedes notar la diferencia cuando usas un número negativo como segundo parámetro y el resultado no es cero:
fuente
mod
yrem
asociado con más fuerza que(-)
. He editado tu comentario ya que parece que no puedo poner cosas de varias líneas en este comentario.(-5) `mod` 3 == 1
Hablando practicamente:
Si conoces a los dos operandos son positivos, por lo general debe utilizar
quot
,rem
oquotRem
para mayor eficiencia.Si no sabe que ambos operandos son positivos, debe pensar en cómo desea que se vean los resultados. Probablemente no quieras
quotRem
, pero quizás tampoco quierasdivMod
. La(x `div` y)*y + (x `mod` y) == x
ley es muy buena, pero redondear la división hacia el infinito negativo (división de estilo Knuth) a menudo es menos útil y menos eficiente que asegurar eso0 <= x `mod` y < y
(división euclidiana).fuente
En caso de que solo desee probar la divisibilidad, siempre debe usar
rem
.Esencialmente
x `mod` y == 0
es equivalente ax `rem` y == 0
, perorem
es más rápido quemod
.fuente