Perché int è solo 2 byte?


9

Quando si utilizza C / C ++ su altre piattaforme, il inttipo è in genere 4 byte (o potenzialmente più). Tuttavia, su Arduino, sono solo 2 byte.

Perché è diverso? Influisce sulle prestazioni se uso sempre il 4 byte long?


2
si noti che intè 4 byte su Arduino Due. A shortsarà 2 byte su tutti gli Ardunios esistenti, ma sottolineo il consiglio degli altri di usare int16_to uint16_t.
Ron,

Risposte:


10

L'ATmega328 utilizzato in molti Arduinos è un microcontrollore a 8 bit. Ciò significa che i registri sono 8 bit, il bus dati è 8 bit, le porte sono 8 bit. Ci sono alcuni aspetti minimi a 16 bit nel sistema (ad esempio uno dei timer), ma quasi tutto è a 8 bit.

Pertanto, la maggior parte delle operazioni gestisce 8 bit alla volta. Lavorare su qualsiasi cosa ad eccezione di 8 bit (ovvero numeri interi a 16 bit o 32 bit e numeri in virgola mobile) richiede ciò che potrebbe essenzialmente essere descritto come emulazione software, in cui il compilatore utilizza più istruzioni per lavorare su queste variabili più grandi.

8 bit è ovviamente adeguato per indirizzare una porta a 8 bit. È anche sufficiente gestire molti contatori di loop, valori di ritorno e caratteri ASCII. Non è davvero abbastanza quando si tratta di numeri. Un int con 8 bit con segno (int8_t) può rappresentare solo -128 -> +127. Unsigned (uint8_t) può rappresentare solo 0 -> 255.

Gli interi a 8 bit sono piuttosto limitanti. C / C ++ int deve rappresentare almeno -32.678 -> +32.767, quindi mappa a int16_t - la dimensione più piccola che lo farà. Questo offre un buon equilibrio tra portata ed efficienza. Ciò è particolarmente importante quando i principianti stanno imparando: l'overflow non è in realtà qualcosa che i non programmatori comprendono.

Tuttavia, ciò ha un impatto sulle prestazioni, poiché la maggior parte delle operazioni a 16 bit richiede almeno il doppio di un'operazione a 8 bit e utilizza il doppio del numero di registri. Questo può o meno fare la differenza per te.

Molti di noi passano ai tipi nativi come int8_t e uint8_t in quanto offrono un controllo molto maggiore.


3
Solo una nota: non è il team di Arduino che ha mappato int a int16_t, "int" è una parola chiave riservata C / C ++ e la mappatura dei tipi fa parte dell'ABI ( gcc.gnu.org/wiki/avr-gcc ) che Gli sviluppatori del compilatore avr-gcc hanno deciso di seguire. Un'altra differenza notevole è nel tipo "doppio" che di solito ha 64 bit di larghezza, mentre in avr-gcc è a 32 bit come "float"
cmaglie,

Grazie. Non so perché l'ho scritto. So che int deve rappresentare 32.678 -> +32.767 (anche se, in realtà, penso che ci fosse un compilatore proprietario per uno dei processori NEC che non ha seguito questo). Penso che sia perché non mi piace nascondere le larghezze sui sistemi embedded - usare int16_t è molto più chiaro.
Cybergibbons,

1
+1 per l'uso di tipi nativi chiari! Sull'Arduino Due, intè un 32 bit! arduino.cc/en/Reference/int
Ron,

3

Un fatto importante sui linguaggi C e C ++ è che i rispettivi standard non definiscono la dimensione (in byte) dei tipi di numeri in virgola mobile e integrale.

Definiscono solo intervalli minimi e relazione tra questi intervalli, ad es

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

Quindi la dimensione di es. Di una intdipende in genere da:

  • la piattaforma di destinazione (processore)
  • il compilatore stesso

stai dicendo che sizeof(short) == sizeof(int) == sizeof(long)è possibile?
Ron,

@ ron-e Teoricamente, sì, sarebbe possibile. In pratica, tuttavia, non l'ho mai visto. Nella maggior parte dei compilatori / piattaforme, ci si potrebbe aspettare (sebbene non sia imposto) che sizeof(short) < sizeof(long).
jfpoilpret,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.