> Tech > La division par zéro

La division par zéro

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

La division par zéro est le bogue explosif le mieux connu du RPG. Dès qu'il rencontre un diviseur de zéro, le programme s'arrête et un message d'exception vient sanctionner le manque de prévoyance du programmeur. A première vue, il semble facile d'éviter la division par zéro. Pour calculer un pourcentage

La division par zéro

de profit, par exemple, il suffit de vérifier si le prix au détail (RtlAmt) est zéro :

C If RtlAmt <> 0
C Eval(HR) PrfPc = (RtlAmt – CstAmt) /
C RtlAmt * 100
C Else
C Eval PrfPc = 0
C EndIf

Mais, la réalité n’est pas toujours aussi simple. Supposons que le prix au détail comprenne la taxe sur les ventes et que l’on veuille calculer le pourcentage de profit en excluant cette taxe. Le calcul devient alors

C Eval(HR) PrfPc = (RtlAmt –
C TaxAmt –
C CstAmt) /
C (RtlAmt –
C TaxAmt) * 100

Le diviseur est maintenant le résultat du prix au détail moins la taxe. Pour éviter une erreur de division par zéro, le calcul sécurisé devient

C If (RtlAmt – TaxAmt ) <> 0
C Eval(HR) PrfPc = (RtlAmt –
C TaxAmt –
C CstAmt) /
C (RtlAmt –
C TaxAmt) * 100
C Else
C Eval PrfPc = 0
C EndIf

Le code ci-dessus est encore facile à  suivre, mais supposons que l’expression arithmétique présente la forme suivante

C Eval A = (B / (C * D)) / (E – F)

Nous testons à  présent les deux résultats intermédiaires pour voir si l’expression peut être effectuée en toute légalité. Ainsi, si le produit de C et D est égal à  zéro ? Si E moins F égale zéro ? Donc, le calcul devient

C If (C * D) <> 0 And
C (E – F) <> 0
C Eval A = (B / (C * D)) / (E – F)
C Else
C Eval A = 0
C EndIf

Deux points sont à  noter dans ce petit fragment de code. Tout d’abord, au fur et à  mesure que la complexité de l’expression augmente, il faut répéter davantage de ses résultats intermédiaire sur l’opération If. Deuxièmement, comme nous dupliquons les expressions, nous pénalisons les performances en évaluant deux fois les expressions. Pour améliorer les performances d’expressions très complexes comprenant la division, on peut fignoler des expressions à  composants comme ceci :

C Eval CD = C * D
C Eval EF = E – F
C If CD <> 0 And
C EF <> 0
C Eval A = (B / CD) / EF
C Else
C Eval A = 0
C EndIf

Si on privilégie les performances sans vouloir fignoler les résultats intermédiaires, on pourrait être tenté de coder ceci :

C If C <> 0 And
C D <> 0 And
C (E – F) <> 0
C Eval A = (B / (C * D)) / (E – F)
C Else
C Eval A = 0
C EndIf

Mais ce code peut encore causer une exception à  l’exécution. Même si C et D ne sont pas zéro, leur produit peut perdre toute précision décimale et, par conséquent, être traité comme un zéro.
Piéger la division par zéro n’est pas toujours aussi simple qu’il y paraît. Pour obtenir un code parfaitement sécurisé, il faut vérifier si chaque diviseur est égal à  zéro, avant d’effectuer une division.
Dans tous les exemples sécurisés ci-dessus, je mets le résultat à  zéro pour éviter une exception de programme. Comme la division par zéro est indéfinie et ne produit pas de résultat, il vaut mieux avertir les utilisateurs qu’une erreur s’est produite. On pourrait, par exemple, fournir l’indication visuelle d’une erreur dans un programme de reporting, comme l’impression d’un point d’exclamation suivi d’une lettre majuscule à  la place de la zone, et en fournissant une légende à  la fin du rapport expliquant les codes d’exception.

Tout comme la division par zéro, la troncature d’ordre supérieur provoque une exception qui stoppe net le programme

Téléchargez cette ressource

Cybersécurité des collectivités : Enjeux, Perspectives & Solutions

Cybersécurité des collectivités : Enjeux, Perspectives & Solutions

Villes, intercommunalités, métropoles, départements et régions sont particulièrement exposés aux risques de cybersécurité. Ce livre blanc Stormshield présente les défis cyber que rencontrent les collectivités, les solutions et perspectives pour qu’elles puissent assurer leur mission d’utilité publique, en toute sécurité.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010