Différence entre u_int8_t, uint_fast8_t et uint_least8_t
Le standard C99 introduit le suivant les types de données. La documentation peut être trouvée ici pour la AVR stdint bibliothèque.
uint8_t
signifie que c'est un 8 bits type non signé.uint_fast8_t
signifie qu'il est le plus rapide unsigned int avec au moins 8
bits.uint_least8_t
signifie que c'est un unsigned int avec au moins 8 bits.
Je comprends uint8_t
et qu'est-ce que uint_fast8_t
( je ne sais pas comment il est mis en œuvre dans le registre de niveau).
1.Pouvez-vous expliquer quel est le sens de "c'est un unsigned int
avec au moins 8 bits"?
2.Comment uint_fast8_t
et uint_least8_t
aider à accroître l'efficacité/code de l'espace par rapport à la uint8_t
?
- Pour votre 1ère question, je peux imaginer que, alors que
uint8_t
est garantie 8 bits,uint_fast8_t
est garantie >= 8 bits, à l'instar d'uneunsigned char
. - Une considération est que
uint8_t
n'existe pas sur les systèmes qui n'ont pas un natif de 8 bits type. Les deux autres seront là. - Vous avez obtenu des réponses qui font référence à "obscur" et "exotique" architectures. Ces termes sont un peu biaisées. Bien sûr, si votre expérience avec les systèmes de bureau, ces architectures sont hors de votre gamme de l'expérience. Mais "je n'ai pas vu ça avant" n'est pas la même chose que "c'est obscur ou exotique". Pour les personnes qui travaillent avec les systèmes embarqués ou les Dsp ces choses sont tout à fait commun.
- Double Possible de La différence de int8_t, int_least8_t et int_fast8_t?
Vous devez vous connecter pour publier un commentaire.
uint_least8_t
est le plus petit type qui a au moins 8 bits.uint_fast8_t
est le type le plus rapide qui a au moins 8 bits.Vous pouvez voir les différences en imaginant des architectures exotiques. Imaginez un 20-bit architecture. Son
unsigned int
a 20 bits (un registre), et sonunsigned char
a 10 bits. Doncsizeof(int) == 2
, mais à l'aide dechar
types nécessite des instructions supplémentaires pour couper les registres de la moitié. Alors:uint8_t
: n'est pas défini (n ° 8 bits type).uint_least8_t
: estunsigned char
, le plus petit type qui est au moins 8 bits.uint_fast8_t
: estunsigned int
, parce que dans mon imaginaire, de l'architecture, un demi-registre variable est plus lent qu'un plein d'inscrire un.int_fast8_t
est variable de 32 bits, vous n'avez pas besoin de faire l'extension du signe avant arithmetric opérations.uintX_fast_t
moins de 32 bits. Vous n'avez même pas à imaginer des architectures pour obteniruint8_t
être indéfini, de prendre pour exemple UNIVAC qui est de 36 bits, je suppose qu'il ychar
est de 9 bits.uint_leastX_t
ouuint_fastX_t
utilisés dans les applications du monde réel.uintX_t
oui, ils sont largement utilisées. On dirait les gens ne sont pas très intéressant dans la transférabilité des architectures exotiques. Ce qui est prévu, même si vous obtenez votre unsigneds droit, votre programme va échouer à un millier de choses différentes.int_fast32_t
est plausible: pour les situations où vous auriez normalement utiliserint
, mais ne veulent pas se briser sur 16 bits plate-forme*int_least*_t
etuint_fast*_t
. Ils sont garantis d'exister et la garantie d'avoir la gamme, ce qui signifie que le code devient réellement portable. Bien sûr, on pourrait faire valoir que l'on pourrait utiliserint
au lieu deint_least16_t
etlong
au lieu deint_least32_t
(mais comment ce fait vous utilisez des nombres de 32 bits au lieu de 16 bits où 16-bits ou 64-bits au lieu de 32 bits où 32 bits est disponible).int
ne pas être susceptible de contenir un pointeur.stdint.h
. Et cet en-tête n'est nécessaire que pour lauintX_t
ceux.[u]int_{least,fast}*_t
dans leur code, mais (2) je n'ai pas encore vu quelqu'un le faire, car il leur a fourni un réel plutôt qu'un hypothétique. En d'autres termes, dans le cas d'utilisation que j'ai vu, les gens ont (dans la pratique) été tout aussi bien hors tension à l'aide deunsigned int
ouunsigned char
ousize_t
ou quoi que ce soit.unsigned int
, il n'est pas clair pourquoi vous avez utilisé que type (et pas une autre). Est-ce parce que c'est exactement 32 bits, ou parce que c'est au moins 32 bits? Ou est-ce parce que c'est le "plus rapide" type? (Sur votre plate-forme...), j'ai, dans un entretien codeur -- ne connais pas vos intentions en utilisantunsigned int
, et j'ai des doutes qu'il pourrait être le mauvais type dans le contexte (et donc responsable pour le bug, je suis à la chasse). Si vous avez écrituint_least32_t
, votre intention est clair, et je peux double-vérifier si vos hypothèses sont correctes.least
etfast
types mixtes de type expressions sont un désordre total. Par exemple, étant donnéuint_least8_t x=1;
ce que devrait être la valeur dex-2 > 5
?uint8_t
il n'y aurait pas de dépassement d'entier, depuis le 2 est signé. Il serait peut-être plus utile de séparer les moins "nombre" et de "l'habillage algébrique ring" de types, de sorte qu'ununum_least8_t
pourrait être n'importe quel type (signé ou non signé--qui peut contenir de 0 à 255 et favorise un type signé alors queuwrap_least8_t
serait un type qui favorise à quelque chose qui, une fois ajouté, subtrated, multiplié, etc. d'obtenir un résultat dont le fond de 8 bits est comme si l'opération n'a été effectuée sur 8 bits type.int
il sera promu àunsigned int
et le résultat sera vrai. Si il est plus petit, il sera promu àint
et le résultat sera faux.uint[ANY]_t a=1; a-2;
vous utilisez la mise en œuvre-comportement défini et il est clairement indiqué dans la norme.uint16_t
ou pas, ce qui rend le l'existence deuint16_t
est Définie par l'Implémentation, maisuint16_t a=1; a-=2;
sera misa
à 65535 sur tout conforme de mise en œuvre qui prend en chargeuint16_t
ne pas invoquer la "Une Règle de Programme" pour justifier de faire quelque chose arbitrairement différents.N
partir de n'importe quel type non signé, puis en ajoutantN
donnera la valeur d'origine lorsque le résultat est contraint à l'original d'un type non signé [je dis une valeur positive, car on ne pouvait imaginer un bizarre système oùint
avait 16 de la valeur des bits, un bit de signe, et 15 bits de remplissage, etunsigned
avait 16 de la valeur des bits et 16 bits de remplissage, etuint16_t
classés en-dessous deint
, où soustrayant -1 à partir d'unuint16_t
donnerait un Comportement non défini]. D'autre part, ...POSIX
systèmes de votre n'avez pas besoinleast
types, vous pouvez utiliseruintn_t
directement.POSIX
systems a une exigenceCHAR_BIT == 8
. Je suis juste en utilisant précise et rapide des types.uint8_t
signifie: donnez-moi un unsigned int d'exactement 8 bits.uint_least8_t
signifie: donnez-moi le plus petit type de unsigned int qui dispose d'au moins 8 bits. Optimiser la consommation de mémoire.uint_fast8_t
signifie: donnez-moi un unsigned int d'au moins 8 bits. Choisissez une taille si elle va faire mon programme plus rapide, en raison de considérations d'alignement. Optimiser la vitesse.Aussi, à la différence de la plaine
int
types, la version signée de la ci-dessus stdint.h types sont garantis 2 du complément de format.stdint.h
sont garantis en complément à deux. Me demande où il va les aider lors de la rédaction d'un code portable.stdint.h
sont plutôt moins utile que l'un peut comme si l'on essaie d'écrire du code portable, car, si elles sont nécessaires à l'utilisation en complément à deux sur le format de stockage, cela n'implique pas qu'ils présenteront en complément à deux sur le comportement d'habillage. Notez également que même sur les plates-formes oùint
est de 32 bits, l'écriture d'une valeur à l'aide d'unint32_t*
et de la lecture à l'aide d'unint*
, ou vice versa, n'est pas garanti.*int
,*long
, et*int32_t
, il n'y a pas moyen de faire un tableau compatible avec tous les trois même sur les plates-formes où les trois types ont la même taille et la représentation.La théorie va quelque chose comme:
uint8_t
est nécessaire pour être exactement 8 bits, mais il n'est pas nécessaire à l'existence. Donc, vous devriez l'utiliser lorsque vous êtes en s'appuyant sur le modulo-256 attribution de comportement* de 8 bits entier et où vous préférez une compilation de l'échec de débordements sur obscur architectures.uint_least8_t
est nécessaire pour être le plus petit possible type entier non signé qui peut stocker au moins 8 bits. Vous pouvez l'utiliser lorsque vous souhaitez réduire l'utilisation de la mémoire des choses comme des tableaux de grande taille.uint_fast8_t
est censé être le "plus rapide" type non signé qui peut stocker au moins 8 bits; cependant, ce n'est pas vraiment garanti pour être le plus rapide pour toute opération sur n'importe quel processeur donné. Vous pouvez l'utiliser dans le traitement de code qui effectue beaucoup d'activités sur la valeur.La pratique, c'est que le "rapide" et "moins" types ne sont pas beaucoup utilisé.
Le "moins" ne sont vraiment utiles que si vous vous souciez de la transférabilité à d'obscurs des architectures avec CHAR_BIT != 8 la plupart des gens ne le font pas.
Le problème avec les "rapides" des types qui "le plus rapide" est difficile à cerner. Un type plus petit peut signifier moins de charge sur la mémoire/système de cache, mais en utilisant un type qui est plus petit que le natif peut exiger des instructions supplémentaires. En outre, ce qui est le mieux peut changer entre les versions architecture, mais les réalisateurs veulent souvent pour éviter de casser ABI dans de tels cas.
De regarder quelques-unes populaire implémentations, il semble que les définitions de uint_fastn_t sont assez arbitraires. la glibc semble les définir comme étant à tout le moins le "native mot" taille " du système en question sans tenir compte du fait que de nombreux processeurs modernes (en particulier 64-bit) ont un soutien spécifique pour les opérations rapides sur les éléments plus petits que leurs natif de la taille de mot. IOS apparemment définit comme l'équivalent de la taille fixe de types. D'autres plates-formes peuvent varier.
Dans l'ensemble, si l'exécution de code serré avec des petits nombres entiers est votre but, vous devriez être bench-marking votre code sur les plates-formes vous vous souciez avec différents types de taille pour voir ce qui fonctionne le mieux.
* Notez que malheureusement modulo-256 attribution de comportement n'implique pas toujours modulo-256 arithmétique, grâce à C de l'entier de la promotion misfeature.
Certains processeurs ne peuvent pas fonctionner de manière aussi efficace sur les petits types de données que sur les grandes. Par exemple, étant donné:
si
y
ont étéuint32_t
un compilateur pour le processeur ARM Cortex-M3 pourrait simplement générermais depuis
y
estuint8_t
le compilateur aurait génère:Le but de "rapide" des types était de permettre à des compilateurs pour remplacer les petits types qui ne pouvaient pas être traitées efficacement avec des plus rapides. Malheureusement, la sémantique de la "rapide" types sont plutôt mal spécifié, qui à son tour feuilles sombres questions de savoir si les expressions sont évaluées en utilisant signé ou non signé mathématiques.
Qui devrait être évident. Cela signifie que c'est un type entier non signé, et que c'est la largeur est d'au moins 8 bits. En effet, cela signifie qu'il peut au moins tenir les nombres de 0 à 255, et il peut certainement pas tenir les nombres négatifs, mais il peut être capable de tenir des numéros supérieurs à 255.
Évidemment, vous ne devez pas utiliser l'un de ces types de si vous prévoyez de stocker un nombre quelconque en dehors de la plage de 0 à 255 (et vous voulez qu'il soit portable).
uint_fast8_t
est nécessaire pour être plus rapide si vous devez utiliser que si votre exigence est que le code soit rapide.uint_least8_t
d'autre part exige qu'il n'y a pas de candidat de moindre taille - donc vous l'utiliser que si la taille est la préoccupation.Et bien sûr, vous utilisez uniquement
uint8_t
lorsque vous avez absolument besoin d'être exactement 8 bits. À l'aide deuint8_t
peut rendre le code non portable commeuint8_t
n'est pas nécessaire à l'existence (car ces petites type entier n'existe pas, sur certaines plateformes)."Rapide" des types d'entiers sont définies de façon à être le plus rapide entier disponible avec au moins la quantité de bits requis (dans votre cas 8).
Une plate-forme peut définir
uint_fast8_t
commeuint8_t
alors il n'y aura absolument pas de différence de vitesse.La raison en est qu'il existe des plates-formes qui sont plus lentes lorsque vous n'utilisez pas leurs natif de la longueur des mots.