Je comprends les différences de capacité et de valeurs qu'ils peuvent représenter, mais il semble que les gens utilisent toujours,Int32
que ce soit approprié ou non. Personne ne semble jamais utiliser la version non signée ( uint
) même si la plupart du temps elle convient mieux car elle décrit une valeur qui ne peut pas être négative (peut-être pour représenter l'ID d'un enregistrement de base de données). De plus, personne ne semble jamais utiliser short/Int16
quelle que soit la capacité requise de la valeur.
Objectivement, y a-t-il des cas où il est préférable d'utiliser uint
ou short/Int16
si oui, quels sont-ils?
null
que positif ou négatif. Si vous le considérez comme quelque chose qui ne peut jamais être négatif ou est toujours positif, vous allez être surpris (et souvent en colère) des résultats parce que cela ne fonctionne pas vraiment de cette façon, surtout en comparaison avec ou soustrait à / à partir de valeurs signées.Réponses:
Je suppose que vous faites référence à une perspective colorée par vos propres expériences où vous n'avez pas travaillé avec des gens qui utilisent correctement les types intégraux. Cela peut bien être un phénomène courant, mais d'après mon expérience, les gens les utilisent également correctement.
L'avantage est l'espace mémoire et le temps processeur, éventuellement l'espace IO également selon que les types sont envoyés sur le câble ou sur un disque. Les types non signés vous donnent des vérifications du compilateur pour vous assurer que vous ne ferez pas certaines opérations qui sont impossibles, en plus d'étendre la plage disponible tout en conservant la plus petite taille pour des performances accrues là où cela peut être nécessaire.
L' utilisation correcte est celle que vous attendez - chaque fois que vous en êtes certain, vous pouvez les utiliser de manière permanente (ne contraignez pas sans certitude ou vous le regretterez plus tard).
public uint NumberOfPeople
), utilisez un type non signé.public byte DamagedToothCount
), utilisez un octet.public short JimmyHoffasBankBalance
).public int HoursSinceUnixEpoch
).public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll
).Ce raisonnement peut être utilisé tout au long du choix entre les types de types signés, non signés et variés et autres, pensez simplement aux vérités logiques des données que vous représentez en réalité.
la source
int
partout sauf si vous savez avec certitude que le domaine problématique limite réellement la valeur - aucune banque ne voudrait limiter les comptes à 33 000 livres sterling (et penser au plaisir quand ça déborde…!).long
. L'économie de mémoire peut bien sûr indirectement gagner du temps en améliorant l'efficacité de la ligne de cache et ainsi de suite, mais OTOH les problèmes d'alignement avec les petits types peuvent indirectement coûter du temps.Bien sûr, il y a des cas où il vaut mieux utiliser
uint
oushort
ouInt16
. Lorsque vous savez que votre plage de données s'adaptera aux contraintes de ce type de variable, vous pouvez utiliser ce type.Dans les environnements à mémoire limitée ou lorsqu'il s'agit de grandes quantités d'objets, il peut être judicieux d'utiliser la plus petite variable de taille. Par exemple, il existe une différence de taille significative pour un tableau d'un million d'éléments de
int
s par rapport àshort
s.Souvent, cela ne se produit pas dans le code réel pour une ou plusieurs des raisons suivantes:
Il y a beaucoup plus de raisons possibles, mais elles se résument à ceci: le temps nécessaire pour décider et utiliser un type de variable différent n'a pas fourni suffisamment d'avantages pour le justifier.
la source
En C, dans des contextes n'impliquant pas de promotion d'entiers , des valeurs non signées ont été spécifiées pour se comporter comme des membres d'un anneau algébrique abstrait "enveloppant" (donc pour tout X et Y, XY produira une valeur unique qui, une fois ajoutée à Y, produira X ), tandis que les types entiers signés étaient spécifiés comme se comportant comme des entiers lorsque les calculs restaient dans une certaine plage et autorisés à tout faire lorsque les calculs allaient au-delà. Cependant, la sémantique numérique en C # est totalement différente. Dans un contexte numérique vérifié, les types signés et non signés se comportent comme des entiers à condition que les calculs restent dans la plage et lancent
OverflowException
quand ils ne le font pas; dans un contexte non contrôlé, ils se comportent tous les deux comme des anneaux algébriques.La seule fois où cela vaut généralement la peine d'utiliser un type de données plus petit que
Int32
lorsqu'il est nécessaire d'emballer ou de déballer des objets pour un stockage ou un transport compact. Si l'on a besoin de stocker un demi-milliard de nombres positifs, et qu'ils seront tous compris entre 0 et 100, utiliser un octet chacun au lieu de quatre permettra d'économiser 1,5 gigaoctet de stockage. C'est une grosse économie. Si un morceau de code a besoin de stocker un total de quelques centaines de valeurs, cependant, faire de chacun d'eux un octet plutôt que quatre permettrait d'économiser environ 600 octets. Probablement pas la peine de s'en préoccuper.En ce qui concerne les types non signés, les seuls moments où ils sont vraiment utiles sont lors de l'échange d'informations ou lors de la subdivision de nombres en morceaux. Si, par exemple, il faut faire des calculs sur des entiers 96 bits, il sera probablement beaucoup plus facile d'effectuer les calculs sur des groupes de trois entiers 32 bits non signés que sur des groupes d'entiers signés. Sinon, il n'y a pas beaucoup de situations où la plage d'une valeur signée 32 ou 64 bits serait inadéquate, mais la même taille de valeur non signée suffirait.
la source
C'est généralement une mauvaise idée d'utiliser des types non signés car ils débordent de manière désagréable.
x = 5-6
est soudainement une bombe à retardement dans votre code. Pendant ce temps, les avantages des types non signés se résument à un seul bit supplémentaire de précision, et si ce bit en vaut la peine pour vous, vous devriez presque certainement utiliser un type plus grand à la place.Il existe des cas d'utilisation où un type plus petit peut avoir un sens, mais à moins que vous ne soyez préoccupé par l'utilisation de la mémoire ou que vous ayez besoin de compresser les données pour la transmission ou l'efficacité du cache ou quelques autres préoccupations, il est généralement vrai qu'il n'y a aucun avantage à utiliser un type plus petit. . De plus, sur de nombreuses architectures, il est en fait plus lent d'utiliser ces types afin qu'ils puissent réellement imposer un faible coût.
la source
i+1>i
dans le1
casi
est signé, avec une foule d'autres comportements méchant. Un débordement non signé peut provoquer un bogue dans un cas d'angle. Un débordement signé peut rendre tout votre programme vide de sens .La conformité CLS est souvent oubliée et peut-être tangentielle à votre question, lorsqu'il s'agit spécifiquement de types .NET . Tous les types ne sont pas disponibles pour toutes les langues basées sur le .NET Framework.
Si vous écrivez du code destiné à être utilisé par des langages autres que C # et souhaitez que ce code soit garanti pour interagir avec autant de langages .NET que possible, vous devez restreindre votre utilisation de type à ceux qui sont conformes CLS.
Par exemple, les premières versions de VB.NET (7.0 et 7.1) ne prenaient pas en charge les entiers non signés (
UInteger
):Les entiers non signés ne sont pas conformes CLS et doivent donc être utilisés avec précaution si vous ne savez pas qui sera votre consommateur de bibliothèque de classe.
la source