Pregunta

Del informe haskell:

  

Las clases quot, rem, div y mod   los métodos satisfacen estas leyes si y es   distinto de cero:

(x `quot` y)*y + (x `rem` y) == x
(x `div`  y)*y + (x `mod` y) == x
     

quot es una división entera truncada   hacia cero, mientras que el resultado de div   se trunca hacia el infinito negativo.

Por ejemplo:

Prelude> (-12) `quot` 5
-2
Prelude> (-12) `div` 5
-3

¿Cuáles son algunos ejemplos de dónde importa la diferencia entre cómo se trunca el resultado?

¿Fue útil?

Solución

Muchos idiomas tienen un " mod " o "%" operador que da el resto después de la división con truncamiento hacia 0; por ejemplo, C, C ++ y Java, y probablemente C #, dirían:

(-11)/5 = -2
(-11)%5 = -1
5*((-11)/5) + (-11)%5 = 5*(-2) + (-1) = -11.
El

Haskell quot y rem están destinados a imitar este comportamiento. Me imagino que la compatibilidad con la salida de algún programa en C podría ser deseable en alguna situación artificial.

Haskell's div y mod , y posteriormente Python / y%, siguen la convención de matemáticos (al menos teóricos de números) siempre truncando hacia abajo división (no hacia 0 - hacia infinito negativo) para que el resto sea siempre no negativo. Así en Python,

(-11)/5 = -3
(-11)%5 = 4
5*((-11)/5) + (-11)%5 = 5*(-3) + 4 = -11.

Haskell div y mod siguen este comportamiento.

Otros consejos

Esta no es exactamente una respuesta a su pregunta, pero en GHC en x86, "Rem en Int se compilará en una sola instrucción de máquina, mientras que divMod trabaja bastante más". Entonces, si se encuentra en una sección de velocidad crítica y trabaja solo con números positivos, "Rem es el camino a seguir".

Un ejemplo simple donde importaría es probar si un número entero es par o impar.

let buggyOdd x = x `rem` 2 == 1
buggyOdd 1 // True
buggyOdd (-1) // False (wrong!)

let odd x = x `mod` 2 == 1
odd 1 // True
odd (-1) // True

Tenga en cuenta que, por supuesto, puede evitar pensar en estos problemas simplemente definiendo impar de esta manera:

let odd x = x `rem` 2 /= 0
odd 1 // True
odd (-1) // True

En general, solo recuerde eso, para y > 0 , x mod y siempre devuelve algo > = 0 mientras que x rem y devuelve 0 o algo del mismo signo que x.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top