Nous savons tous 0/0
est Undefined
et renvoie une erreur si je devais le mettre dans une calculatrice, et si je devais créer un programme (en C au moins) le système d' exploitation devait prendre fin quand je tente de diviser par zéro.
Mais ce que je me demandais, c’est si l’ordinateur tente même de diviser par zéro ou s’il dispose simplement d’une «protection intégrée», de sorte que, lorsqu'il «voit», 0/0
il renvoie une erreur avant même d’essayer de la calculer.
math
error-handling
arithmetic
Ankush
la source
la source
Réponses:
La CPU a une détection intégrée. La plupart des architectures de jeux d'instructions spécifient que la CPU va se connecter à un gestionnaire d'exceptions pour une division entière par zéro (je ne pense pas que le fait que le dividende soit égal à zéro ne le dérange pas).
Il est possible que la vérification d'un diviseur zéro soit effectuée en parallèle dans le matériel avec la tentative de division. Cependant, la détection de la condition incriminée annule effectivement la division et les pièges. Nous ne pouvons donc pas vraiment savoir si une partie de celui-ci a tenté la division ou non.
(Le matériel fonctionne souvent ainsi, faisant plusieurs choses en parallèle et choisissant ensuite le résultat approprié, car chacune des opérations peut alors être lancée immédiatement au lieu de procéder à la sérialisation du choix de l'opération appropriée.)
Le même mécanisme d'interruption vers exception sera également utilisé lorsque la détection de dépassement de capacité est activée, ce que vous demandez habituellement en utilisant différentes instructions d'ajout / de sous / mul (ou un indicateur sur ces instructions).
La division en virgule flottante a également une détection intégrée pour la division par zéro, mais renvoie une valeur différente ( IEEE 754 spécifie NaN ) au lieu d'être capturée par un gestionnaire d'exceptions.
En théorie, si le processeur omettait de détecter une tentative de division par zéro, les problèmes pourraient inclure:
la source
Cela dépend de la langue, du compilateur, de l'utilisation d'entiers ou de nombres à virgule flottante, etc.
Pour les nombres à virgule flottante, la plupart des implémentations utilisent la norme IEEE 754 , dans laquelle la division par 0 est bien définie. 0/0 donne un résultat bien défini de NaN (pas un nombre), et x / 0 pour x 0 donne soit + Infinity soit -Infinity, en fonction du signe de x.
Dans des langages tels que C, C ++, etc., la division par zéro appelle un comportement indéfini. Donc, selon la définition du langage, tout peut arriver. Surtout des choses que vous ne voulez pas arriver. Comme si tout fonctionnait parfaitement bien lorsque vous écrivez le code et détruisez les données lorsque votre client les utilise. Donc, du point de vue de la langue, ne faites pas cela . Certaines langues garantissent le blocage de votre application. c'est à eux de décider comment cela est mis en œuvre. Pour ces langues, la division par zéro va planter.
De nombreux processeurs ont une sorte d'instruction "diviser" intégrée, qui se comportera différemment selon le processeur. Sur les processeurs Intel 32 bits et 64 bits, les instructions "diviser" planteront votre application lorsque vous essayez de diviser par zéro. D'autres processeurs peuvent se comporter différemment.
Si un compilateur détecte qu'une division par zéro va se produire lorsque vous exécutez du code et qu'il est gentil avec ses utilisateurs, il vous avertira probablement et générera une instruction intégrée "divide" afin que le comportement soit le même. même.
la source
EXCEPTION_INT_DIVIDE_BY_ZERO
valeur de laEXCEPTION_RECORD
qui sera gérée par le (je l' espère) installé CONSTRUIT Exception Handling HandlerOn dirait que vous vous demandez ce qui se passerait si quelqu'un fabriquait un processeur qui ne vérifiait pas explicitement la valeur zéro avant la division. Ce qui arriverait dépend entièrement de la mise en œuvre de la division. Sans entrer dans les détails, un type de mise en oeuvre produirait un résultat avec tous les bits définis, par exemple 65535 sur un processeur 16 bits. Un autre pourrait raccrocher.
la source
Étant donné que
x/0
cela n’a aucun sens, les ordinateurs doivent toujours vérifier la division par zéro. Il y a un problème ici: les programmeurs veulent calculer(a+b)/c
sans avoir à vérifier si ce calcul est logique. La réponse sous-jacente à la division par zéro par le CPU + le type de numéro + le système d'exploitation + le langage consiste à faire quelque chose d'assez grave (par exemple, bloquer le programme) ou à faire quelque chose de trop anodin sens tel que le point flottant IEEENaN
, un nombre qui n’est pas un nombre).Dans un contexte ordinaire, un programmeur doit savoir si
(a+b)/c
cela a du sens. Dans ce contexte, il n'y a aucune raison de vérifier la division par zéro. Si la division par zéro se produit, et si le langage machine + le langage d'implémentation + le type de données + le système d'exploitation répondent à cela pour faire planter le programme, c'est bien. Si la réponse est de créer une valeur qui pourrait éventuellement polluer chaque numéro du programme, ce n'est pas grave.Dans le monde de l'informatique à haute fiabilité, ni "drastique" ni "trop bénigne" ne constitue la meilleure chose à faire. Ces réponses par défaut peuvent tuer un patient, écraser un avion de ligne ou faire exploser une bombe au mauvais endroit. Dans un environnement de haute fiabilité, un programmeur qui écrit
(a+b)/c
est sélectionné à mort lors de la révision du code ou, à notre époque, peut-être automatiquement à mort par un outil vérifiant les constructions verboten. Dans cet environnement, ce programmeur devrait plutôt avoir écrit quelque chose dans le sens dediv(add(a,b),c)
(et éventuellement une vérification du statut d'erreur). Sous le capot, les fonctions / macrosdiv
(ainsi que lesadd
) protègent contre une division par zéro (ou un débordement dans le cas deadd
). Ce que cette protection implique est très spécifique à la mise en œuvre.la source
Nous savons maintenant que
x/0
et0/0
n'ont pas de réponses bien définies. Qu'advient-il si vous essayez de calculer0/0
quand même?Sur un système moderne, le calcul est transmis à la MPU au sein de la CPU et est signalé comme une opération non conforme
NaN
.Sur un système beaucoup plus ancien, tel que les ordinateurs personnels des années 80 ne disposant pas de division sur puce, le calcul était effectué avec le logiciel utilisé. Il y a quelques choix possibles:
0
1
log(0)
et le logiciel utiliserait ses routines de traitement des erreurs ou se bloquerait0
et e 0 = 1, donnant un résultat de1
En d'autres termes, ce qui se produirait dépendrait de la mise en œuvre et il serait possible d'écrire un logiciel qui produirait des résultats corrects et prévisibles pour chaque valeur, mais des valeurs apparemment étranges resteraient
0/0
néanmoins cohérentes en interne.la source
NaN
dans les nombres entiers.very inefficient
pour la division. Le coût pour l'arithmétique est (addition = soustraction) <= multiplication <= division. Si vous n'avez pas de MPU capable de diviser dans le même nombre de cycles d'horloge que l'addition (généralement un), la division est plus onéreuse que l'addition et la soustraction et généralement plus chère que la multiplication.