Question

À partir du rapport haskell:

  

Les classes quot, rem, div et mod   les méthodes satisfont à ces lois si y est   non nul:

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

quot est une division entière tronquée   vers zéro, alors que le résultat de div   est tronqué vers l'infini négatif.

Par exemple:

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

Quels sont quelques exemples de cas où la différence entre la façon dont le résultat est tronqué est importante?

Était-ce utile?

La solution

De nombreuses langues ont un " mod " ou "% " opérateur qui donne le reste après division avec troncature vers 0; Par exemple, C, C ++ et Java, et probablement C #, diraient:

(-11)/5 = -2
(-11)%5 = -1
5*((-11)/5) + (-11)%5 = 5*(-2) + (-1) = -11.
Les quot et rem de Haskell sont destinés à imiter ce comportement. J'imagine que la compatibilité avec la sortie d'un programme C peut être souhaitable dans certaines situations artificielles.

Les div et les mod de Haskell, puis les / et% de Python, suivent la convention des mathématiciens (au moins les théoriciens du nombre) en tronquant toujours bas division (pas vers 0 - vers l'infini négatif) pour que le reste soit toujours non négatif. Ainsi en Python,

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

Les codes div et mod de Haskell suivent ce comportement.

Autres conseils

Ce n'est pas exactement une réponse à votre question, mais dans GHC sur x86, quotRem on Int compile en une seule instruction machine, alors que divMod fait un peu plus de travail. Donc, si vous êtes dans une section critique en matière de vitesse et que vous travaillez uniquement sur des nombres positifs, l'option "Rem est le meilleur choix".

Voici un exemple simple dans lequel il serait important de vérifier si un entier est pair ou impair.

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

Notez, bien sûr, que vous pourriez éviter de penser à ces problèmes en définissant simplement étrange de cette façon:

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

En général, rappelez-vous que, pour y > 0 , x mod y renvoie toujours quelque chose > = 0 tandis que x rem y renvoie 0 ou quelque chose du même signe que x.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top