Warum ist int nur 2 Bytes?

9

Bei Verwendung von C / C ++ auf anderen Plattformen intbeträgt der Typ normalerweise 4 Byte (oder möglicherweise mehr). Auf Arduino sind es jedoch nur 2 Bytes.

Warum ist es anders? Beeinträchtigt es die Leistung, wenn ich longstattdessen immer 4 Byte verwende?

Peter Bloomfield
quelle
2
Beachten Sie, dass dies int4 Bytes auf dem Arduino Due sind. A shortwird bei allen vorhandenen Ardunios 2 Byte groß sein, aber ich betone die Ratschläge der anderen, int16_toder uint16_t.
Ron

Antworten:

10

Der in vielen Arduinos verwendete ATmega328 ist ein 8-Bit-Mikrocontroller. Dies bedeutet, dass Register 8-Bit sind, der Datenbus 8-Bit ist, die Ports 8-Bit sind. Das System weist einige minimale 16-Bit-Aspekte auf (z. B. einen der Timer), aber fast alles ist 8-Bit.

Daher verarbeiten die meisten Operationen jeweils 8 Bit. Die Arbeit an etwas anderem als 8-Bit (dh 16-Bit- oder 32-Bit-Ganzzahlen und Gleitkommazahlen) erfordert eine Software-Emulation, bei der der Compiler mehrere Anweisungen verwendet, um diese größeren Variablen zu bearbeiten.

8-Bit ist offensichtlich ausreichend, um einen 8-Bit-Port zu adressieren. Es reicht auch aus, mit vielen Schleifenzählern, Rückgabewerten und ASCII-Zeichen umzugehen. Es ist jedoch nicht genug, wenn es um Zahlen geht. Ein vorzeichenbehaftetes 8-Bit-Int (int8_t) kann nur -128 -> +127 darstellen. Unsigned (uint8_t) kann nur 0 -> 255 darstellen.

8-Bit-Ganzzahlen sind ziemlich einschränkend. C / C ++ int muss mindestens -32.678 -> +32.767 darstellen, entspricht also int16_t - der kleinsten Größe, die dies tun wird. Dies ergibt ein gutes Gleichgewicht zwischen Reichweite und Effizienz. Dies ist besonders wichtig, wenn Anfänger lernen - Überlauf ist nicht wirklich etwas, was Nicht-Programmierer verstehen.

Dies hat jedoch Auswirkungen auf die Leistung, da die meisten 16-Bit-Operationen mindestens doppelt so lange dauern wie eine 8-Bit-Operation und doppelt so viele Register verwenden. Dies kann für Sie einen Unterschied machen oder auch nicht.

Viele von uns wechseln zu nativen Typen wie int8_t und uint8_t, da Sie dadurch weitaus mehr Kontrolle haben.

Cybergibbons
quelle
3
Nur eine Anmerkung: Es ist nicht das Arduino-Team, das int int16_t zugeordnet hat, "int" ist ein reserviertes C / C ++ - Schlüsselwort, und die Typzuordnung ist Teil des ABI ( gcc.gnu.org/wiki/avr-gcc ), das das Die Entwickler des avr-gcc-Compilers haben beschlossen, zu folgen. Ein weiterer bemerkenswerter Unterschied ist der "doppelte" Typ, der normalerweise 64 Bit breit ist, während der avr-gcc 32 Bit wie "float" ist
cmaglie
Vielen Dank. Ich bin mir nicht sicher, warum ich das geschrieben habe. Ich weiß, dass int 32.678 -> +32.767 darstellen muss (obwohl ich glaube, dass es einen proprietären Compiler für einen der NEC-Prozessoren gab, der dem nicht folgte). Ich denke, das liegt daran, dass ich Breiten auf eingebetteten Systemen nicht gerne verstecke - die Verwendung von int16_t ist viel klarer.
Cybergibbons
1
+1 für die Verwendung klarer nativer Typen! Auf dem Arduino Due ist ein int32-Bit! arduino.cc/en/Reference/int
Ron
3

Eine wichtige Tatsache bei C- und C ++ - Sprachen ist, dass ihre jeweiligen Standards nicht die Größe (in Bytes) von Integral- und Gleitkommazahlentypen definieren.

Sie definieren nur minimale Bereiche und Beziehungen zwischen diesen Bereichen, z

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

Die Größe eines Beispiels inthängt also normalerweise ab von:

  • die Zielplattform (Prozessor)
  • der Compiler selbst
jfpoilpret
quelle
Wollen Sie damit sagen, dass dies sizeof(short) == sizeof(int) == sizeof(long)möglich ist?
Ron
@ ron-e Theoretisch wäre das ja möglich. In der Praxis habe ich das jedoch noch nie gesehen. In den meisten Compilern / Plattformen könnte man das erwarten (obwohl es nicht vorgeschrieben ist) sizeof(short) < sizeof(long).
jfpoilpret