Je suis programmée pendant un certain temps en C ++, mais soudainement eu un doute et voulait préciser avec la communauté Stackoverflow. P>
Lorsqu'un entier est divisé par un autre entier, nous savons tous que le résultat est un entier et comme sage, un flotteur divisé par le flotteur est également un flotteur. P>
Mais qui est responsable de fournir ce résultat? Est-ce le compilateur ou l'instruction DIV? P>
6 Réponses :
Cela dépend de la question de savoir si votre architecture a em> a Si vous n'avez qu'une instruction de division entier, ou uniquement une instruction de division de points flottants, le compilateur sera conforme à un code ou générera un appel à une bibliothèque de support mathématique pour gérer la division. Les instructions de division sont notoirement lentes, la plupart des compilateurs tenteront de les optimiser si possible (par exemple, remplacez-les par des instructions de décalage ou de précalculer le résultat pour une division des constantes de compilation). p> div code> instruction. Si votre architecture dispose des instructions de division d'entiers et de points flottants, le compilateur émettra la bonne instruction pour le cas spécifié par le code. La norme linguistique spécifie les règles de promotion de type et si la division entier ou en inteir doit être utilisée dans chaque situation possible. P>
Le compilateur décidera au moment de la compilation Quelle forme de division requise en fonction des types de variables utilisées - à la fin de la journée, une instruction DIV (ou FDIV) d'une forme ou d'une autre s'impliquera. p>
Sauf si les variables sont des constantes de la compilation, auquel cas le compilateur «assumera la responsabilité» et aucune instruction n'est produite.
@Potatoswatter: Pas entièrement vrai; Le compilateur doit évaluer les expressions constantes intégrées et peut évaluer d'autres expressions constantes. C'est à dire. Float X = 1.0 / 3.0 CODE> peut être évalué par le compilateur ou peut aboutir à un choix de FDIV-Compiler.
Les instructions de division matérielle n'incluent presque jamais la conversion entre le point entier et le point flottant. Si vous obtenez des instructions de division du tout (ils sont parfois laissés de côté, car un circuit de division est large et compliqué), ils sont pratiquement certains d'être «Divisez-le par INT, produisent int» et «diviser le flotteur par flotteur, produisent du flotteur» . Et ce sera généralement que les entrées et la sortie sont toutes de la même taille. P>
Le compilateur est responsable de la construction de toute opération écrite dans le code source, au-dessus de ces primitives. Par exemple, en C, si vous divisez un float par une INT, le compilateur émettra une conversion into-float puis une fracture de flotteur. P>
(existent farfely existent. Je ne sais pas, mais je ne le mettrais pas au-delà du VAX d'avoir eu des instructions de type "diviser par int". L'itanium n'a pas vraiment eu une instruction de division, mais sa "Diviser Helper" était seulement em> pour un point flottant, vous avez dû fake faux diviser au-dessus de la fracture de flotteur!) p>
Il h. En ce qui concerne les "exceptions négligentes", comme vous les appelez, vous avez probablement utilisé une seule maintenant pour écrire cette réponse. L'instruction X86 (ou plus précisément x87) pour Diviser Float par Int i> est appelée Fidiv.
Et ce n'est pas le seul point où la farce de X86 met la honte de Vax :).
Hah! Eh bien, ce serait le x87. Ils n'ont pas fait rien i> la voie normale avec cette chose.
la norme C99 définit "lorsque les entiers sont divisés, le résultat de l'opérateur est le quotient algébrique avec une partie fractionnelle mis au rebut. "Et ajoute dans une note de bas de page qui" ceci est souvent appelée "troncature vers zéro" " p>
Historiquement, la spécification de la langue est responsable. P>
Pascal Définit sa opérateurs de sorte qu'utiliser En C, il a été décidé que la même distinction doit être faite en casting l'un des opérandes entier à un / code> pour la division renvoie toujours un
réel code> (même si vous l'utilisez pour diviser 2 entiers), et si vous voulez diviser les entiers et obtenir Un résultat entier, vous utilisez l'opérateur
div code> à la place. (Visual Basic a une distinction similaire et utilise l'opérateur
\ code> pour la division entière qui renvoie un résultat entier.) P>
float code> si vous vouliez un résultat de point flottant. Il est devenu convention de traiter des types de points entier par rapport à la manière dont vous décrivez dans de nombreuses langues dérivées de C. Je soupçonne que cette convention peut être originaire de Fortran. P>
L'une des règles les plus importantes de la norme C ++ est la règle "comme si" la règle: p>
Les descriptions sémantiques de cette norme internationale définissent une machine abstraite non déterministe paramétrée. Cette norme internationale n'entre aucune exigence sur la structure des implémentations conformes. En particulier, ils n'ont pas besoin de copier ou d'émuler la structure de la machine abstraite. Des implémentations conformes sont plutôt nécessaires pour émuler (uniquement) le comportement observable de la machine abstraite comme expliqué ci-dessous. P> blockQuote>
Qui par rapport à votre question signifie que cela n'a pas d'importance à quelle composante la division est-elle aussi longue que celle-ci. Il peut être effectué par un code de machine code> div code>, il peut être effectué par un code plus compliqué s'il n'y a pas d'instruction appropriée pour le processeur en question. P>
Il peut aussi: P>
- Remplacez l'opération par une opération de décalage bit si approprié et susceptible d'être plus rapide. LI>
- Remplacez l'opération par un littéral si calculable au moment de la compilation ou une affectation si par exemple. Lors du traitement X / Y, il peut être affiché au moment de la compilation que Y sera toujours 1. Li>
- Remplacez l'opération par un lancer d'exception si elle peut être affichée lors de la compilation de la compilation qu'il s'agira toujours d'une division entière par zéro. Li> ol>
Pourrait-il refuser de compiler s'il pouvait déduire au moment de la compilation que le quotient serait toujours zéro ou est-il légitime pour un programme C entièrement conforme de contenir une instruction comme x = 1 / (x-x); à condition qu'une telle instruction n'exécute jamais réellement?
@supercat: C'est parfaitement légitime. C'est l'exécution i> d'une division par zéro qui provoque un comportement indéfini.
@supercat Si vous souhaitez produire un programme qui a toujours des erreurs, c'est votre entreprise! Il est difficile d'apprendre aux gens des erreurs sans eux (bien que dans certaines langues, vous devez faire des trucs comme si (vrai == faux) code> Pour tromper les compilateurs en vous laissant compiler). Il serait certainement raisonnable et utile que le compilateur produit un avertissement non normalisé.
... L'important est que si un expert infaillible sur la langue indique ", il se comportera donc" alors il doit faire ce que l'expert dit comme vu de l'extérieur. Comment cela fait-il que c'est au compilateur. Ces bits qui sont "indéfinis" sont où l'expert dira "Je ne sais pas ce que ça va faire" (En réalité, il va probablement expliquer le mauvais code, vous savez quels experts sont comme), mais défini uniquement s'applique à "à l'extérieur "Vues. Cela est important pour permettre des optimisations et une grande partie de la STL dépend de cela pour ne pas vraiment sucer les termes de performance.
Le compilateur peut également remplacer x / 2.5 code> avec
x * 0.4 code>. Ceci est en fait commun car la multiplication est souvent plus rapide que la division.
Votre question n'a pas vraiment de sens. L'instruction DIV ne fait pas rien em> par lui-même. Peu importe la taille que vous criez, même si vous essayez de le corrompre, cela ne prend pas la responsabilité de rien em> p>
Lorsque vous programmez dans un langage de programmation [x], il est seul responsable du compilateur [x] à créer un programme qui fait ce que vous avez décrit dans le code source em>. p>.
Si une division est demandée, le compilateur décide comment faire une division se produire. Cela pourrait arriver en générant l'opcode pour l'instruction Mais c'est Et l'instruction DIV ne sait rien sur la norme C ++. Un compilateur C ++, d'autre part, est écrit em> dans le seul but de comprendre la norme C ++ et de transformer le code en fonction de celui-ci. P>
Le compilateur est div code> si la CPU que vous ciblez en a une. Il pourrait être de préciser la division au moment de la compilation et d'insérer simplement le résultat directement dans le programme (en supposant que les deux opérandes soient connus au moment de la compilation), ou cela pourrait être fait en générant une séquence d'instructions qui ensemble imiter em> une division. p>
Est-ce que vous divisez les constantes ou les variables?