2010-06-17 29 views
8

¿Cuál es la razón para usar números con signo como índices en .Net?Números sin signo versus números con signo

En Python, puede indexar desde el final de una matriz enviando números negativos, pero este no es el caso en .Net. No es fácil para .Net agregar una característica más adelante, ya que podría romper otro código, quizás usando reglas especiales (sí, una mala idea, pero creo que sucede) en la indexación.

No es que alguna vez haya necesitado indexar matrices de más de 2,147,483,647 de tamaño, pero realmente no puedo entender por qué eligen los números con signo.

¿Puede ser porque es más normal usar números con signo en el código?

Edit: acaba de encontrar estos enlaces:

The perils of unsigned iteration in C/C++

Signed word lengths and indexes

Edit2: Ok, un par de otras buenas razones de la rosca Mateo Flaschen publicación:

  • histórico razones, ya que es un lenguaje parecido al de C
  • Interopera con c
+0

+1, excelente pregunta. – Blindy

+1

Consulte [¿Por qué Array.Length es una int, y no una uint] (http://stackoverflow.com/questions/6301/why-is-array-length-an-int-and-not-an-uint). –

+0

posible duplicado de [¿Por qué .NET utiliza int en lugar de uint en ciertas clases?] (Http://stackoverflow.com/questions/782629/why-does-net-use-int-instead-of-uint-in- ciertas clases) – nawfal

Respuesta

3

Por simplicidad, por supuesto. ¿Te gusta trouble haciendo aritmética de tamaño con enteros sin signo?

+1

Un punto muy bueno y válido – simendsjo

+0

El ejemplo que publicó representa un ejemplo perfecto de una práctica de mala programación. Si alguien es un codificador aficionado, ni los enteros con signo lo salvarán del buffer por debajo/por encima. –

2

Unsigned no cumple con CLS.

+0

Pero Microsoft hizo las especificaciones CLS ¿verdad? Tuvieron la última palabra en este caso y eligieron usar números con signo. – Blindy

+1

@Blindy: Creo que querían que las especificaciones de CLS fueran lo más inclusivas posibles, y no todos los idiomas admiten números sin firmar (por ejemplo, VB6 e incluso si VB6 no es un lenguaje de CLS, supongo que podrían haber deseado aumentar las posibilidades de interoperabilidad). –

+0

@Blindy: Java ni siquiera tiene unsigned. – kizzx2

4

Puede ser por la larga tradición de utilizar un valor por debajo de 0 como índice no válido. Los métodos como String.IndexOf devuelven -1 si el elemento no se encuentra. Por lo tanto, el valor de retorno debe estar firmado. Si los consumidores de índice requerirían valores sin signo, tendría que a) verificar yb) emitir el valor para usarlo. Con los índices firmados, solo necesita el cheque.

+0

Parece plausible, pero ese es el único ejemplo que se me ocurre. Usar un número negativo como índice es un error de tiempo de ejecución. IndexOf podría haberse implementado de otra manera. – simendsjo

+0

Otro ejemplo es [List .BinarySearch] (http://msdn.microsoft.com/en-us/library/w4e7fxsh.aspx) donde el resultado es "El índice de elemento basado en cero en la lista ordenada , si se encuentra el elemento, de lo contrario, un número negativo que es el complemento bit a bit del índice del siguiente elemento que es más grande que el elemento o, si no hay un elemento más grande, el complemento bit a bit de Count ". –

0

La utilidad principal de los números sin signo surge cuando se componen números más grandes de los más pequeños y viceversa. Por ejemplo, si uno recibe cuatro bytes sin signo de una conexión y desea considerar su valor, tomada como un todo, como un entero de 32 bits, utilizando los tipos sin signo significa que uno puede decir simplemente:

 
    value = byte0 | (byte1*256) | (byte2*65536) | (byte3*16777216); 

Por el contrario, si los bytes fueron firmados, una expresión como la anterior sería más complicada.

No estoy seguro de que realmente veo ninguna razón para que un lenguaje diseñado hoy en día no incluir versiones sin firmar de todos los tipos más corto que el tipo entero más larga firmado, con la semántica que todos entero (que significa discretos-cantidad-numéricos, en lugar que cualquier tipo particular) las operaciones que cabrán completamente dentro del tipo firmado más grande se realizarán por defecto como si estuvieran operando sobre ese tipo. Incluir una versión sin firmar del tipo más grande firmado complicaría la especificación del lenguaje (ya que uno debería especificar qué operaciones deben caber dentro del rango del tipo con signo, y qué operaciones deben caber dentro del rango del tipo sin firmar), pero de lo contrario debería haber no hay problema en el diseño de un lenguaje para que if (unsigned1 - unsigned2 > unsigned3) arroje un resultado "numéricamente correcto" incluso cuando unsigned2 es mayor que unsigned2 [si se quiere un wraparound sin signo, uno especifica explícitamente if ((Uint32)(unsigned1 - unsigned2) > unsigned3)].Un lenguaje que especifique dicho comportamiento sería una gran mejora con respecto al desorden que existe en C (justificable, dado su historial), C# o vb.net.

Cuestiones relacionadas