Lorsque j'exécute le code C suivant sur une machine Intel ... ... La sortie est la suivante: p> -512.000000 -> 0
-448.000000 -> 0
-384.000000 -> 0
-320.000000 -> 0
-256.000000 -> 0
-192.000000 -> 0
-128.000000 -> 0
-64.000000 -> 0
0.000000 -> 0
64.000000 -> 64
128.000000 -> 128
192.000000 -> 192
256.000000 -> 0
320.000000 -> 64
384.000000 -> 128
448.000000 -> 192
512.000000 -> 0
3 Réponses :
Je vais répondre à 3 dans ma propre question mais ne signalera pas cela comme la réponse acceptée. L'astuce semble être un simple casting dans la coercition: utiliser (int) ou (court) fonctionne aussi. Je suis toujours intéressé de savoir où se trouve la cause de ce problème: compilateur ou processeur. P> p>
Notez que ce n'est pas réellement un correctif portable. Vous êtes dans un comportement indéfini dès que vous dépassez la plage représentable du type de destination pour toute conversion du flotteur entier. Si vous voulez vraiment Garantie B> Comportement multi-plateformes, vous pouvez faire quelque chose comme c = f <0? 0: F> uchar_max? Uchar_max: f; code>, mais même cela ne perturbe pas le comportement des nans.
Le problème spécifique que vous avez affaire à l'endansion. Essayez de remplacer l'une ou l'autre implémentation avec En général, le comportement dépendra de l'endansnité, de la longueur des mots et des capacités de points flottants du processeur et de la manière dont le compilateur cible cela. Le bras est bi-endian, de sorte que cela pourrait ou ne pas correspondre à la commande IA octet. Il semble qu'il n'y ait pas non plus de garantie générale qu'une implémentation C prend en charge le même format de point flottant que d'autres: fixe- Taille Types de points flottants . p>
Utilisez-vous cela dans le code de production? Je serais très fort pour la raison pour laquelle cela doit être fait. Un ou l'autre type n'est probablement pas utilisé comme prévu. Les solutions de contournement ne vont pas être élégantes. P> C = * ((char *) et F + taille de taille de (flotteur) - 1); code> ou quelque chose de similaire pour obtenir le dernier octet du flotteur et voir s'il correspond à le résultat pour l'autre plate-forme. P>
L'endansion n'affectera pas ce problème. En outre, le processeur iPad et les croustilles Intel sont à la fois petit-Endian.
La norme C n'a pas de règles très difficiles pour ce que vous essayez de faire. Voici le paragraphe en question, de la section 6.3.1 opérandes arithmétiques strong> (spécifiquement section 6.3.1.4 réel flottant et entier fort>): P>
Lorsqu'une valeur finie de type flottant réel est convertie en un type d'entier autre que Il y a même une note de bas de page plus spécifique sur le cas exact que vous posez sur: p>
L'opération de reste effectuée lorsqu'une valeur de type entier est convertie en type non signé, il n'est pas nécessaire de ne pas être effectuée lorsqu'une valeur de type flottant réel est convertie en type non signé. Ainsi, la gamme de valeurs flottantes véritables portables est Les réponses à vos questions numérotées, donc: p>
_bool code> strong>, la partie fractionnée est rejetée (c.-à-d. La valeur est tronquée vers zéro) . Si la valeur de la partie intégrale ne peut pas être représentée par le type entier, le comportement est indéfini. P>
blockQuote>
(- 1, utype_max + 1) code>. P>
blockQuote>
utypemax + 1 code> pour votre cas est
256 code>. Vos cas incompatibles sont tous des nombres négatifs. Après la troncature, ils sont toujours négatifs et sont en dehors de la plage (-1, 256), de sorte qu'ils sont fermement dans la zone de «comportement indéfini». Même certains des cas correspondants que vous avez montrés, où le numéro de point flottant est supérieur ou égal à
256 code>, ne sont pas garantis pour travailler - vous obtenez juste de la chance. P>
Exactement. Ceci est un comportement indéfini, simple et simple.
Merci pour les réponses les gars (le commentaire de Stephen Canon à ma propre réponse ci-dessous). Je vais probablement mettre la valeur du flotteur dans une gamme saines avant la coercition, à partir de vos commentaires, je comprends que c'est une mauvaise pratique de compter sur le «comportement indéfini».
Je ne connaissais pas très bien ce genre de choses, mais ma première réaction est que c'est une mauvaise idée d'essayer de contraindre un flotteur dans un caractère non signé sur n'importe quelle plate-forme sur n'importe quelle architecture.
Je ne suis pas d'accord avec toi Brian. La précision n'est pas un problème ici, mais la performance est. J'utilise la nature "Emballage" du caractère non signé pour rester dans les 0-255 frontières. Ceci est, Afaik (et ont lu plusieurs articles) non pas une technique rare.
@ZMIPPIE: Le comportement que vous voyez est la nature "saturation", qui est assez courante par ex. Ensembles d'instructions SIMD.