¿Por qué int solo tiene 2 bytes?

9

Cuando se utiliza C / C ++ en otras plataformas, el inttipo suele ser de 4 bytes (o potencialmente más). Sin embargo, en Arduino, son solo 2 bytes.

¿Por qué es diferente? ¿Afecta el rendimiento si siempre uso el byte de 4 long?

Peter Bloomfield
fuente
2
tenga en cuenta que intson 4 bytes en el Arduino Due. A shortserá de 2 bytes en todos los Ardunios existentes, pero enfatizo los consejos de los demás para usar int16_to uint16_t.
Ron

Respuestas:

10

El ATmega328 utilizado en muchos Arduinos es un microcontrolador de 8 bits. Esto significa que los registros son de 8 bits, el bus de datos es de 8 bits, los puertos son de 8 bits. Hay algunos aspectos mínimos de 16 bits en el sistema (por ejemplo, uno de los temporizadores), pero casi todo es de 8 bits.

Por lo tanto, la mayoría de las operaciones manejan 8 bits a la vez. Trabajar en cualquier cosa excepto 8 bits (es decir, números enteros de 16 bits o 32 bits y números de coma flotante) requiere lo que esencialmente podría describirse como emulación de software, donde el compilador utiliza múltiples instrucciones para trabajar en estas variables más grandes.

8 bits es obviamente adecuado para direccionar un puerto de 8 bits. También es suficiente para tratar con muchos contadores de bucle, valores de retorno y caracteres ASCII. Sin embargo, no es realmente suficiente cuando se trata de números. Un int de 8 bits con signo (int8_t) solo puede representar -128 -> +127. Unsigned (uint8_t) solo puede representar 0 -> 255.

Los enteros de 8 bits son bastante limitantes. C / C ++ int debe representar al menos -32,678 -> +32,767 por lo que se asigna a int16_t, el tamaño más pequeño que lo hará. Esto proporciona un buen equilibrio de alcance y eficiencia. Esto es especialmente importante cuando los principiantes están aprendiendo: el desbordamiento no es realmente algo que los no programadores entiendan.

Sin embargo, esto tiene un impacto en el rendimiento, ya que la mayoría de las operaciones de 16 bits requieren al menos el doble de tiempo que una operación de 8 bits y utilizan el doble de registros. Esto puede o no hacer una diferencia para usted.

Muchos de nosotros cambiamos a los tipos nativos como int8_t y uint8_t, ya que le da mucho más control.

Cybergibbons
fuente
3
Solo una nota: no es el equipo Arduino el que asignó int a int16_t, "int" es una palabra clave reservada de C / C ++, y la asignación de tipo es parte del ABI ( gcc.gnu.org/wiki/avr-gcc ) que el Los desarrolladores del compilador avr-gcc decidieron seguir. Otra diferencia notable es en el tipo "doble" que generalmente tiene 64 bits de ancho, mientras que en el avr-gcc es de 32 bits como "flotador"
cmaglie
Gracias. No estoy seguro de por qué escribí eso. Sé que int debe representar 32,678 -> +32,767 (aunque, en realidad, creo que hubo un compilador propietario para uno de los procesadores NEC que no siguió esto). Creo que es porque no me gusta ocultar anchos en sistemas embebidos: usar int16_t es mucho más claro.
Cybergibbons
1
¡+1 por el uso de tipos nativos claros! En el Arduino Due, ¡un intes de 32 bits! arduino.cc/en/Reference/int
Ron
3

Un hecho importante sobre los lenguajes C y C ++ es que sus estándares respectivos no definen el tamaño (en bytes) de los tipos de números de punto flotante y integral.

Solo definen rangos mínimos y la relación entre estos rangos, por ejemplo

range(short) <= range(int) < range(long)

Por lo tanto, el tamaño de, por ejemplo, un intnormalmente dependerá de:

  • la plataforma de destino (procesador)
  • el compilador en sí
jfpoilpret
fuente
¿Estás diciendo que sizeof(short) == sizeof(int) == sizeof(long)es posible?
Ron
@ ron-e Teóricamente, sí, eso sería posible. En la práctica, sin embargo, nunca he visto eso. En la mayoría de los compiladores / plataformas, uno podría esperar (aunque no se impone) eso sizeof(short) < sizeof(long).
jfpoilpret