Entiendo las diferencias en capacidad y valores que pueden representar, pero parece que las personas siempre usan Int32
independientemente de si es apropiado. Nadie parece usar la versión sin signo ( uint
) aunque muchas veces se ajusta mejor, ya que describe un valor que no puede ser negativo (tal vez para representar una ID de un registro de base de datos). Además, nadie parece usarlo short/Int16
independientemente de la capacidad requerida del valor.
Objetivamente, ¿hay casos en los que es mejor usar uint
o, de short/Int16
ser así, cuáles son?
null
que positivo o negativo. Si lo considera como algo que nunca puede ser negativo o siempre es positivo, se sorprenderá (y a menudo se enojará) con los resultados porque realmente no funciona de esa manera, especialmente cuando se compara o se resta a / de valores firmados.Respuestas:
Sospecho que te estás refiriendo a una perspectiva coloreada por tus propias experiencias en la que no has trabajado con personas que usan los tipos integrales correctamente. Esto puede ser una ocurrencia común, pero según mi experiencia, la gente también los usa correctamente.
El beneficio es el espacio de memoria y el tiempo de CPU, posiblemente también el espacio de E / S dependiendo de si los tipos se envían alguna vez por cable o a un disco. Los tipos sin firmar le brindan comprobaciones del compilador para asegurarse de que no realizará ciertas operaciones que son imposibles, además de extender el rango disponible al tiempo que mantiene el tamaño más pequeño para un mayor rendimiento cuando sea necesario.
El uso correcto es el que esperaría: cada vez que sepa con certeza , puede usarlos permanentemente (no restrinja sin certeza o se arrepentirá más adelante).
public uint NumberOfPeople
), use un tipo sin signo.public byte DamagedToothCount
), use un byte.public short JimmyHoffasBankBalance
).public int HoursSinceUnixEpoch
).public long MyReallyGreatAppsUserCountThisIsNotWishfulThinkingAtAll
).Este razonamiento se puede utilizar para elegir entre tamaños de tipos y otros firmados, sin signo y variados, solo piense en las verdades lógicas de los datos que representa en la realidad.
fuente
int
todas partes, a menos que sepa con certeza que el dominio del problema realmente restringe el valor, ningún banco querría limitar las cuentas a 33K quid (y piense en la diversión cuando eso se desborda ...!).long
. Por supuesto, el ahorro de memoria puede ahorrar tiempo indirectamente al mejorar la eficiencia de la línea de caché, etc., pero OTOH los problemas de alineación con tipos pequeños pueden indirectamente costar tiempo.Claro, hay casos en los que es mejor usar
uint
oshort
oInt16
. Cuando sepa que su rango de datos se ajustará a las restricciones de ese tipo de variable, entonces está bien usar ese tipo.En entornos con memoria limitada o cuando se trata con grandes cantidades de objetos, puede tener sentido usar la variable de tamaño más pequeño. Por ejemplo, hay una diferencia significativa en el tamaño de un conjunto de millones de elementos de
int
s vs.short
s.A menudo, eso no sucede en el código real por una o más de las siguientes razones:
Hay muchas más razones posibles, pero se reducen a esto: el tiempo involucrado en decidir y usar un tipo de variable diferente no proporcionó suficiente beneficio para justificar hacerlo.
fuente
En C, en contextos que no involucran la promoción de enteros , se especificaron valores sin signo para comportarse como miembros de un anillo algebraico abstracto "envolvente" (por lo que para cualquier X e Y, XY producirá un valor único que, cuando se agrega a Y, producirá X ), mientras que los tipos enteros con signo se especificaban como comportándose como enteros cuando los cálculos se mantenían dentro de un cierto rango, y se les permitía hacer cualquier cosa cuando los cálculos iban más allá de eso. La semántica numérica en C #, sin embargo, es totalmente diferente. Cuando se encuentra dentro de un contexto numérico verificado, los tipos con signo y sin signo se comportan como enteros siempre que los cálculos permanezcan dentro del rango y se arrojen
OverflowException
cuando no lo hacen; en un contexto no controlado, ambos se comportan como anillos algebraicos.El único momento en el que generalmente vale la pena usar cualquier tipo de datos más pequeño que
Int32
cuando es necesario empacar o desempacar cosas para almacenamiento o transporte compacto. Si uno necesita almacenar 500 millones de números positivos, y todos estarán en el rango de 0 a 100, usar un byte cada uno en lugar de cuatro ahorrará 1.5 gigabytes de almacenamiento. Eso es un gran ahorro. Sin embargo, si una pieza de código necesita almacenar un total de un par de cientos de valores, hacer que cada uno de ellos sea un byte en lugar de cuatro ahorraría aproximadamente 600 bytes. Probablemente no valga la pena molestarse.Con respecto a los tipos sin signo, las únicas veces que son realmente útiles son cuando se realiza el intercambio de información o cuando se subdividen los números en partes. Si, por ejemplo, uno necesita hacer cálculos matemáticos en enteros de 96 bits, probablemente será mucho más fácil realizar los cálculos en grupos de tres enteros de 32 bits sin signo, que en grupos de enteros con signo. De lo contrario, no hay muchas situaciones en las que el rango de un valor con signo de 32 o 64 bits sea inadecuado, pero sería suficiente el mismo tamaño de valor sin signo.
fuente
En general, es una mala idea usar tipos sin signo porque se desbordan de formas desagradables.
x = 5-6
De repente es una bomba de tiempo en su código. Mientras tanto, los beneficios de los tipos sin signo se reducen a un solo bit adicional de precisión, y si ese bit lo vale para usted, seguramente debería usar un tipo más grande.Hay casos de uso en los que un tipo más pequeño podría tener sentido, pero a menos que le preocupe el uso de la memoria o necesite empacar datos para la transmisión o la eficiencia de la caché o un puñado de otras preocupaciones, generalmente es el caso de que no sea beneficioso usar un tipo más pequeño . Además, en muchas arquitecturas, en realidad es más lento usar estos tipos para que puedan imponer un pequeño costo.
fuente
i+1>i
en1
sii
está firmado, junto con toda una serie de otros comportamientos desagradable. El desbordamiento sin firmar puede causar un error en un caso de esquina. El desbordamiento firmado puede hacer que todo su programa no tenga sentido .A menudo olvidado y posiblemente tangencial a su pregunta, cuando se trata específicamente con tipos .NET, es el cumplimiento de CLS . No todos los tipos están disponibles para todos los idiomas creados en .NET Framework.
Si escribe código para que lo consuman otros idiomas que no sean C # y desea que se garantice que ese código interopere con la mayor cantidad posible de idiomas .NET, debe restringir su uso de tipos a aquellos que cumplan con CLS.
Por ejemplo, las primeras versiones de VB.NET (7.0 y 7.1) no admitían enteros sin signo (
UInteger
):Los enteros sin signo no son compatibles con CLS y, por lo tanto, deben usarse con cuidado si no está seguro de quién será el consumidor de la biblioteca de su clase.
fuente