164 votes

Pourquoi C n'a-t-il pas de flotteurs non signés?

Je sais, la question semble étrange. Les programmeurs pensent, parfois trop. Veuillez lire ce qui suit...

C-je utiliser des entiers signés et non signés 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 de beaucoup plus.

J'aime ces mises en garde. Ils m'aident à garder mon code propre.

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 signe-drapeau de la flotte. Je suis super heureux avec le flotteur comme ils sont maintenant. Je voudrais juste pour marquer 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 à propos de tout langage de programmation qui prend en charge non signé nombres en 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. Miss-utilisation (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.

137voto

Brian R. Bondy Points 141769

Pourquoi le 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 le C++ n'a 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 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é.

25voto

Skizz Points 30682

Il y a une différence significative entre les entiers signés et non signés entiers en C/C++:

value >> shift

signé valeurs de quitter le top peu inchangé (signe étendre), des valeurs non signées dégager le dessus peu à peu.

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. Réfléchissez à ceci:

float a = 2.0f, b = 10.0f, c;
c = a - b;

Quelle est la valeur de c? -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:

float a = 2.0f, b = 10.0f, c = 20.0f, d = 3.14159f, e;
e = (a - b) / d + c;

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, on ne pouvait 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.

10voto

ephemient Points 87003

(En aparté, Perl 6 vous permet d'écrire

subset Nonnegative::Float of Float where { $_ >= 0 };

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'offre pas. 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.

10voto

Treb Points 11153

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.

Edit: Après la lecture de la réponse de 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 ;-)

5voto

Tobias Wärre Points 589

Je suppose que cela dépend du fait que seules les spécifications de points flottants IEEE sont signées et que la plupart des langages de programmation les utilisent.

wikipedia sur les nombres à virgule flottante

Edit: De plus, comme d’autres l'ont fait remarquer, la plupart des matériels ne prennent pas en charge les flottants non négatifs. Le type de flotteurs normal est donc plus efficace car il prend en charge le matériel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X