Vous ne pouvez pas Mod Zero?

Pourquoi X % 0 une expression non valide?

J’ai toujours pensé que X % 0 devrait être égal à X. Puisque vous ne pouvez pas diviser par zéro, la réponse ne devrait-elle pas être naturellement le rest, X (tout ce qui rest)?

Le standard C ++ (2003) dit au §5.6 / 4,

[…] Si le deuxième opérande de / ou% est nul, le comportement n’est pas défini ; […]

Autrement dit, les expressions suivantes invoquent undefined-behavior (UB):

 X / 0; //UB X % 0; //UB 

Notez également que -5 % 2 n’est PAS égal à -(5 % 2) (comme Petar semble suggérer dans son commentaire à sa réponse). C’est défini par l’implémentation. La spécification dit (§5.6 / 4),

[…] Si les deux opérandes sont non négatifs, le rest est non négatif; sinon, le signe du rest est défini par la mise en œuvre .

Cette réponse n’est pas pour le mathématicien. Cette réponse tente de donner de la motivation (au prix d’une précision mathématique).

Mathématiciens: Voir ici.

Programmeurs: Rappelez-vous que la division par 0 n’est undefined . Par conséquent, le mod , qui repose sur la division, est également undefined .


Ceci représente la division pour X et D positifs; il est constitué de la partie intégrale et de la partie fractionnaire:

 (X / D) = integer + fraction = floor(X / D) + (X % D) / D 

Réorganiser, vous obtenez:

 (X % D) = D * (X / D) - D * floor(X / D) 

En substituant 0 pour D :

 (X % 0) = 0 * (X / 0) - 0 * floor(X / 0) 

Puisque la division par 0 est undefined :

 (X % 0) = 0 * undefined - 0 * floor(undefined) = undefined - undefined = undefined 

X % D est par définition un nombre 0 <= R < D tel qu'il existe Q pour que

 X = D*Q + R 

Donc, si D = 0 , aucun tel nombre ne peut exister (parce que 0 <= R < 0 )

Je pense que pour obtenir le rest de X % 0 vous devez d’abord calculer X / 0 qui donne l’infini, et essayer de calculer le rest de l’infini n’est pas vraiment possible.

Cependant, la meilleure solution en accord avec votre reflection serait de faire quelque chose comme ça

 REMAIN = Y ? X % Y : X 

Une autre façon de concevoir le problème pourrait être facile à comprendre:

Ignorant pour le moment la question du signe de l’argument, a % b pourrait facilement être réécrit sous la a - ((a / b) * b) . L’expression a / b n’est pas définie si b est égal à zéro. Dans ce cas, l’expression globale doit l’être également.

En fin de compte, le module est en fait une opération de division, donc si a / b n’est pas défini, il n’est pas déraisonnable de s’attendre à ce a % b le soit également.

X% Y donne un résultat dans la plage entière [0, Y]. X% 0 devrait donner un résultat supérieur ou égal à zéro et inférieur à zéro.

vous pouvez échapper à la casse de (A% B) pour son type float identity mod (a, b) pour float (B) = b = 0.0, qui est indéfini ou défini différemment entre 2 implémentations, pour éviter les erreurs de logique (crash brutal) en faveur des erreurs arithmétiques …

en calculant mod([a*b],[b])==b*(a-floor(a))
INSTREAD DE
mod([a],[b]) informatique mod([a],[b])

où [a * b] == votre axe des abscisses, au fil du temps [b] == le maximum de la courbe de bascule (qui ne sera jamais atteinte) == la dérivée première de la fonction de bascule

https://www.shadertoy.com/view/MslfW8