Pourquoi ne pas C ont unsigned flotteurs?
Je sais, la question semble étrange. Les programmeurs pensent, parfois trop. Veuillez lire ce qui suit...
En C j'utilise signed
et unsigned
entiers beaucoup. J'aime le fait que le compilateur me prévient si je fais les choses comme l'affectation d'un entier signé un unsigned variable. Je reçois des avertissements si je compare signé avec des entiers non signés et beaucoup beaucoup plus.
J'aime ces mises en garde. Ils m'aident à garder mon code correct.
Pourquoi n'avons-nous pas le même luxe pour les flotteurs? Une racine carrée aura certainement jamais de retour d'un nombre négatif. Il y a d'autres lieux où un négatif float valeur n'a pas de sens. Candidat parfait pour un unsigned char.
Btw - je ne suis pas vraiment envie sur le single bit supplémentaire de précision que j'ai pu obtenir en supprimant le bit de signe de la flotte. Je suis super heureuse avec float
s comme ils sont maintenant. Je voudrais juste marque un flotteur non signés parfois, et obtenir le même genre de mises en garde que je reçois avec des entiers.
Je ne suis pas au courant de tout langage de programmation qui prend en charge non signé nombres à virgule flottante.
Aucune idée de pourquoi ils n'existent pas?
EDIT:
Je sais que la FPU x87 n'a pas d'instructions à traiter avec des unsigned char. Permet suffit d'utiliser la signature de flotter instructions. Utilisation abusive (par exemple aller au-dessous de zéro) pourrait être considéré comme un comportement indéterminé de la même manière que le débordement des entiers signés est pas défini.
- Intéressant, pouvez-vous poster un exemple d'un cas où ce paramètre typage a été utile?
- litb, a votre commentaire adressent à moi? si oui, je n'ai pas l'obtenir
- Iraimbilanja ouais 🙂 fabs ne pouvez pas retourner un nombre négatif, car il renvoie la valeur absolue de son argument
- La droite.je n'ai pas demander comment un hypothétique unsignedfloat pourrait aider corectness.ce que j'ai posée était la suivante:dans quelle situation avez-pipenbrinck trouver Int ce paramètre typage utile(ce qui l'amène toseek le même mécanisme pour les chars).la raison pour laquelle je demande, c'est que je trouve unsigneds tout à fait inutile en ce qui concerne typesafety
- Il y a un unsigned micro-optimisation de point-à-plage de vérifier: ((unsigned)(p-min))<(max-min), qui a seulement une branche, mais, comme toujours, il est préférable de profil pour voir si cela aide vraiment (j'ai surtout utilisé sur 386 cœurs, donc je ne sais pas comment les Processeurs modernes face).
- Je pense que vous demandez une analyse statique du code. Ne signifie pas qu'il doit être mis en œuvre par le système de type.
- Coin: "Une racine carrée aura certainement jamais de retour d'un nombre négatif." est un bon math truisme, mais pas nécessairement le cas avec
sqrt()
dans C. 1) de Nombreuses plates-formessqrt(-0.0)
-->-0.0
un nombre négatif, en un sens, bien que n'étant pas une valeur négative. 2)sqrt(-1.0)
--> la mise en œuvre définies par le comportement qui pourrait revenir à -1.0. - Il n'a pas vraiment faire une différence sur la base de ce que vous demandez. parce que dans la plupart des cas, il y a une erreur d'exécution, de sorte que le compilateur ne pas l'attraper, et vous devez les vérifier de toute façon. vraiment je ne vois pas comment cela aide avec n'importe quoi. signé flotteurs de ne pas faire trop de différence à mon avis.
Vous devez vous connecter pour publier un commentaire.
Pourquoi C++ n'est pas prise en charge pour les flotteurs est parce qu'il n'y a pas d'équivalent en code machine des opérations pour le PROCESSEUR à exécuter. Donc, il serait très inefficace pour la soutenir.
Si C++ ne le soutenir, alors vous seriez parfois à l'aide d'un unsigned flotter et ne pas réaliser que votre performance a été tué. Si C++ appuyé, puis chaque opération de virgule flottante aurait besoin d'être vérifié pour voir s'il est signé ou non. Et pour les programmes qui ne des millions d'opérations en virgule flottante, ce n'est pas acceptable.
Donc la question serait pourquoi ne pas le matériel maîtres d'œuvre en charge. Et je pense que la réponse à cela est qu'il n'y avait pas non signé flotteur standard défini à l'origine. Puisque les langues comme compatible, même s'il a été ajouté les langues ne pouvais pas en faire usage. Pour voir la virgule flottante spec, vous devriez regarder la La norme IEEE 754 en virgule Flottante.
Vous pouvez obtenir autour de ne pas avoir un unsigned type à virgule flottante bien que par la création d'un unsigned float classe qui encapsule un float ou double et lance des avertissements si vous essayez de passer en un nombre négatif. C'est moins efficace, mais sans doute si vous n'utilisez pas intensément, vous ne se soucient que de légères pertes de performances.
Je vois vraiment l'utilité d'avoir un unsigned char. Mais le C/C++ tend à choisi d'efficacité qui fonctionne le mieux pour tout le monde sur la sécurité.
int
's, tous les le signe liées à la vérification de type pourrait se produire au moment de la compilation. OP suggère queunsigned float
serait mis en œuvre en tant que régulierfloat
avec la compilation des vérifications pour s'assurer que certains non-significatif d'opérations ne sont jamais réalisées. La résultante en code machine et de la performance pourrait être identique, indépendamment du fait que votre flotte sont signés ou non.Il y a une différence significative entre les entiers signés et non signés entiers en C/C++:
signé valeurs de quitter le top peu inchangé (signe étendre), des valeurs non signées clair la dessus bits.
La raison, il n'est pas non signé flotteur est que vous réalisez rapidement à toutes sortes de problèmes si il n'y a pas de valeurs négatives. Considérez ceci:
Quelle est la valeur de c ont? -8. Mais ce que cela signifierait dans un système sans les nombres négatifs. FLOAT_MAX - 8 peut-être? En fait, cela ne fonctionne pas comme FLOAT_MAX - 8 est FLOAT_MAX en raison de la précision des effets donc les choses sont encore plus tordu. Et si c'était une partie d'une expression plus complexe:
Ce n'est pas un problème pour les entiers en raison de la nature de l'2 du système du complément.
Également envisager de fonctions mathématiques standard: sin, cos et tan ne fonctionne que pour la moitié de leurs valeurs d'entrée, vous ne trouvez pas le journal de valeurs < 1, vous ne pouvez pas résoudre des équations quadratiques: x = (-b +/- racine (b.b - 4.un.c)) /2.un, et ainsi de suite. En fait, il ne serait probablement pas travailler pour une fonction complexe que ceux-ci tendent à être mis en œuvre en tant que polynôme approximations qui serait d'utiliser des valeurs négatives quelque part.
Donc, non signé flotteurs sont assez inutile.
Mais cela ne veut pas dire qu'une classe qui vont vérifie les valeurs float n'est pas utile, vous pouvez le serrage de valeurs pour un champ donné, par exemple RGB calculs.
2's complement
, il n'y aura pas de problème avec le fait d'avoir unsigned flotteurs?value >> shift for signed values leave the top bit unchanged (sign extend)
Êtes-vous sûr de cela? Je pensais que c'était de la mise en œuvre définies par le comportement, au moins pour les valeurs signées.(En aparté, Perl 6 vous permet d'écrire
et puis vous pouvez utiliser
Nonnegative::Float
tout comme vous le feriez pour tout autre type.)Il n'y a pas de support matériel pour les opérations à virgule flottante, donc C n'est pas l'offrir. C est principalement conçu pour être portable assemblée", c'est-à proximité du métal que vous pouvez être sans être attaché à une plate-forme spécifique.
[modifier]
C est comme de l'assemblée: ce que vous voyez est exactement ce que vous obtenez. Un implicite "je vais vérifier que ce flotteur est positif pour vous" va à l'encontre de sa philosophie de conception. Si vous le voulez vraiment, vous pouvez ajouter
assert(x >= 0)
ou similaire, mais vous devez le faire explicitement.of ...
ne pas analyser.Je crois que le unsigned int a été créé en raison de la nécessité d'une plus grande valeur de la marge de la signature de l'int pourrait offrir.
Un flotteur a beaucoup plus de marge, donc il n'a jamais été un "physique" besoin d'un unsigned char. Et comme vous le soulignez vous-même dans votre question, la plus-1 bits de précision n'est rien de le tuer pour.
Edit:
Après la lecture de la réponse par Brian R. Bondy, j'ai modifier ma réponse:
Il est certainement exact que le Cpu n'a pas non signé de l'exploitation des hydravions. Cependant, je maintiens mon idée que c'était une décision de conception basée sur les raisons que j'ai indiqué ci-dessus 😉
Je pense que Treb est sur la bonne voie. Il est plus important pour les entiers que vous avez un unsigned type correspondant. Ce sont ceux qui sont utilisés dans de décalage de bits et utilisé dans bits-cartes. Un bit de signe est juste dans la manière. Par exemple, le droit-transfert d'une valeur négative, la valeur est définie par l'implémentation en C++. Que faire avec un entier non signé ou de débordement de ces a parfaitement défini la sémantique parce qu'il n'y est aucune de ces bits dans le chemin.
Donc pour les entiers au moins, la nécessité d'un autre type non signé est plus fort que juste de donner des avertissements. Tous les points ci-dessus ne doivent pas être considérés pour des flotteurs. Donc, il y a, je pense, pas de réel besoin de support matériel pour eux, et C déjà de ne pas les soutenir à ce point.
Je suppose que ça dépend que de la norme IEEE floating points spécifications n'est signé et que la plupart des langages de programmation les utiliser.
wikipédia articla sur des nombres à virgule flottante ieee
Edit: Aussi, comme indiqué par d'autres, la plupart du matériel ne prend pas en charge non-négative de la flotte, de sorte que le type normal de chars sont plus efficace, car il est le support matériel.
C99 prend en charge les nombres complexes, et un type de la forme générique de la racine, de sorte
sqrt( 1.0 * I)
sera négatif.Les auteurs ont mis en évidence une légère brillance ci-dessus, en ce que je faisait allusion au type générique
sqrt
macro plutôt que de la fonction, et il sera de retour un scalaire valeur en virgule flottante par la troncature du complexe de son composant réel:Il contient aussi un cerveau-prout, comme la partie réelle de la racine carrée de tout nombre complexe est positif ou nul, et sqrt(1.0*I) correspond à la racine carrée de(0,5) + sqrt(0.5)*j'ai pas -1.0.
sqrt(-0.0)
produit souvent-0.0
. Bien sûr -0.0 n'est pas un négatif valeur.Je pense que la raison principale est que, non signé flotteurs aurait vraiment utilisations limitées par rapport à unsigned ints. Je n'achète pas l'argument que c'est parce que le matériel n'est pas en charge. Les processeurs plus anciens n'avait pas de virgule flottante capacités à tous, on a tous des émules dans le logiciel. Si non signés, les flotteurs ont été utiles, ils auraient été mis en œuvre dans le logiciel et le matériel ont emboîté le pas.
Entier non signé types en C sont définies de manière à obéir aux règles de l'abstrait algébrique de l'anneau. Par exemple, pour toute valeur de X et Y, l'ajout de X-Y pour Y donnera X. entier non signé types sont garantis à obéir à ces règles dans tous les cas qui n'impliquent pas la conversion en, ou à partir de n'importe quel autre type numérique [ou unsigned types de tailles différentes], et que la garantie est l'une des fonctionnalités les plus importantes de ces types. Dans certains cas, il est intéressant de donner la possibilité de représenter les nombres négatifs en échange des garanties supplémentaires seulement unsigned types peuvent fournir. Les types à virgule flottante, que ce soit signé ou non, ne peut pas respecter toutes les règles de l'algébrique de l'anneau [par exemple, ils ne peuvent pas garantir que X+Y-Y sera égal à X], et, en effet, IEEE n'autorise même pas à respecter les règles d'une classe d'équivalence [en exigeant que certaines valeurs de comparer l'inégalité à eux-mêmes]. Je ne pense pas qu'un "unsigned" virgule flottante type de respecter les axiomes qui ordinaire à virgule flottante type ne pouvait pas, donc je ne suis pas sûr de ce que les avantages qu'elle offre.
Je soupçonne que c'est parce que le sous-jacent processeurs ciblés par les compilateurs C n'ont pas une bonne façon de traiter avec des unsigned des nombres à virgule flottante.
IHMO c'est parce que l'appui à la fois signés et non signés, les types à virgule flottante dans le matériel ou le logiciel ne soit pas trop gênant,
Pour les types integer, nous pouvons utiliser le même unité logique pour signé et non signé entier opérations dans la plupart des situations à l'aide de la belle propriété de 2 en complément, parce que le résultat est identique dans ces cas pour l'add, sub, non-élargissement de mul et la plupart des opérations bit à bit. Pour les opérations qui font la différence entre signés et non signés version, on peut encore part de la majorité de la logique. Par exemple
INT_MIN
. Aussi théoriquement possible, ce n'est probablement pas utilisé sur du matériel, il est pourtant utile sur les systèmes qui prennent en charge qu'un seul type de comparaison (comme 8080 ou 8051)Les systèmes qui utilisent le 1er complément aussi juste besoin d'un peu de modification de la logique, car c'est tout simplement le bit de retenue enroulé autour de la bit le moins significatif. Pas sûr au sujet de signe-amplitude systèmes, mais il semble comme ils utilisation 1 en complément à l'interne de sorte que la même chose s'applique
Malheureusement nous n'avons pas ce luxe pour les types à virgule flottante. Simplement en libérant le bit de signe, nous allons avoir la version non signée. Mais alors, que devons-nous utiliser que peu de?
Mais les deux choix ont besoin d'un plus additionneur afin de prendre en compte l'ensemble de la gamme de valeur. Qui augmente la complexité de la logique, tandis que l'additionneur du haut bits se trouve là inutilisés la plupart du temps. Encore plus de circuits seront nécessaires pour les multiplications, de divisions ou d'autres opérations complexes
Sur les systèmes qui utilisent le logiciel en virgule flottante vous avez besoin de 2 versions pour chaque fonction, ce qui n'était pas prévue pendant le temps de la mémoire est tellement cher, ou vous aurez à trouver une certaine "difficulté" manière de partager des parties de l'signés et non signés fonctions
Cependant la virgule flottante existé longtemps avant de C a été inventé, je crois donc que le choix dans C était dû à l'absence de support matériel à cause de la raison que j'ai mentionné ci-dessus
Cela dit, il existe plusieurs spécialisé unsigned les formats à virgule flottante, principalement pour le traitement de l'image, comme Khronos group 10 et 11 bits à virgule flottante de type