9
votes

iPhone: Les flotteurs lancés vers des INT non signés sont définis sur 0 s'ils sont négatifs?

Essayez-le:

volatile float bob = -344.0f;
unsigned int fred = (unsigned int)bob;

printf("%d\n",fred);


3 commentaires

@KennyTM: Une tentative aléatoire de l'arrêter d'optimiser les choses.


Vieux fil, mais j'ai heurté un peu plus de détails autour de cela récemment. Avec xcode 7.2.x, la coulée d'un flotteur négatif à un abréviaire non signé a entraîné une valeur enveloppée sur toutes les plates-formes IOS testées. Cependant, avec Xcode 7.3.1, le même code entraîne une troncature à zéro sur iPad 3 et envelopper sur iPhone 6.


Est-ce que cela répond à votre question?


4 Réponses :


12
votes

Ceci doit être attendu - jeter un flottant négatif à un INT non signé des résultats dans un comportement non défini (UB). Si vous souhaitez que la valeur enveloppante (qui est également UB, BTW), vous auriez alors besoin de vous lancer vers un (signé) Int d'abord, puis de non signé INT. Idéalement, vous ne devriez pas compter sur UB du tout et trouver une meilleure façon de faire ce que vous devez faire.


4 commentaires

Alors, pourquoi n'est-ce pas un problème avec VC ++ ou le compilateur PSP?


@matt: parce que vous comptez sur un comportement indéfini


@matt: It est un problème sur ces compilateurs si vous attendez que l'INT soit 0, qui est tout aussi raisonnable que cela s'attendait à ce que cela s'attendait à ce que cela s'attend C'est le problème avec un comportement non défini: vous ne pouvez pas raisonnablement s'attendre à ce que aucune chose particulière se produise. Cela pourrait envelopper, cela pourrait aller à 0, cela pourrait envoyer des courriels suggestifs à votre employeur - il est complètement non défini ce qu'il va faire.


@matt, juste parce qu'il y a un résultat intuitif ne signifie pas que le comportement est défini par la norme. En particulier, la conversion "évidente" est en fait très différente de la conversion de la même valeur d'un type d'intégral signé. On peut certainement voir pourquoi une implémentation pourrait préférer retourner 0 plutôt qu'un résultat peu confusant et potentiellement déroutant. Quoi qu'il en soit, il serait raisonnable et conforme, mais d'une manière, elle est également incompatible plutôt que simplement non immentée.



-1
votes

Cast via un INT signé.


0 commentaires

4
votes

§6.3.1.4 de la norme C:

Quand une valeur finie de véritable flottante Le type est converti en un type entier autre que _bool, la partie fractionnée est jeté (c'est-à-dire que la valeur est tronqué vers zéro). Si la valeur de la partie intégrante ne peut pas être représenté par le type entier, le le comportement est indéfini.

Donc, comme Paul R dit, c'est un comportement indéfini.


0 commentaires

0
votes

Cette conversion est indéfinie et donc non portable.

Selon C99 §6.3.1.4 Note de bas de page 50:

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 plage de valeurs flottantes réelles portables est (-1, utype_max + 1).

Et étant donné que cette conversion est connue de ne pas être portable, c'est une interprétation assez raisonnable de retourner 0 plutôt qu'une conversion particulière aléatoire. Il y a au moins deux raisons pour cela: (1) Paigne du code non portable plutôt que de le propager, et (2) il suffit de laisser tomber le signe est extrêmement différent de ce qui se passe lorsque la même valeur d'un type intégré est convertie. pas clair que toute alternative particulière est une meilleure idée.


0 commentaires