Warum gibt es so viele numerische Typen (Bit, Int, Float, Double, Long)?

9

Ich habe PHP, Java und C gelernt. Jetzt bin ich gespannt, warum es so viele Arten von numerischen Datentypen wie Bit, Int, Float, Double und Long gibt. Warum nicht nur einen Typ für Zahlen erstellen?

Hat das einen Nutzen? Vielleicht können wir Speicher sparen, wenn wir ganze Zahlen verwenden, um so kleine Zahlen zu speichern?

GusDeCooL
quelle
6
Zusätzlich zu HorusKols Antwort: Die Typen 'float' und 'integer' unterscheiden sich von Natur aus. Floats können sehr große Zahlen aufnehmen, aber wenn die Größe der Zahl zunimmt, nimmt die Genauigkeit ab. Diese Ungenauigkeit ist auf die Art und Weise zurückzuführen, wie Floats gespeichert werden. Im Gegensatz dazu ist der Wertebereich, den Sie in einer Ganzzahl speichern können, recht begrenzt, aber der Wert ist immer genau, sodass Sie Werte viel einfacher vergleichen können. Es gibt auch zwei verschiedene Arten von Verhalten mit Division - Ganzzahlen werden automatisch auf die nächste ganze Zahl abgeschnitten, Floats nicht. Jedes dieser Verhaltensweisen ist für verschiedene Situationen nützlich.
Kampu
Javascript hat nur einen Nummerntyp auf der Oberfläche.
Esailija
@kampu: Tatsächlich können Ganzzahlen in vielen Sprachen eine beliebige Zahl speichern, solange der (virtuelle) Speicher groß genug ist, um sie darzustellen.
Jörg W Mittag
1
@ JörgWMittag: Dieser Fragesteller spricht jedoch eindeutig von statischen Sprachen, nicht von dynamischen Sprachen wie beispielsweise Python. CPython selbst implementiert die Ganzzahl "Unlimited Range" als Array von 32-Bit-Ints, wobei das letzte Bit in jedem Int verwendet wird, um anzuzeigen, ob noch mehr Bits übrig sind. Ganzzahlen können auch nur eine ganze Zahl speichern . Das bedeutet, dass ein Float mit unendlichem Speicher Werte mit der Genauigkeit speichern kann (Infinity Aleph Eins), während Ganzzahlen Werte nur mit der Genauigkeit speichern können ( Infinity Aleph Zero ).
Kampu
@kampu: Da alle Zahlen auch bei unendlichem Speicher durch eine Reihe von Bits dargestellt werden, gibt es immer eine Eins-zu-Eins-Zuordnung zwischen Gleitkommazahlen und ganzen Zahlen. Ich glaube also nicht, dass Aleph man in Frage kommt.
Kommen Sie

Antworten:

17

Es gibt zwei Gründe, warum Sie sich mit den verschiedenen numerischen Datentypen befassen sollten.

1. Speicher speichern

for(long k=0;k<=10;k++)
{
    //stuff
}

Warum ein Long verwenden, wenn es genauso gut eine Ganzzahl oder sogar ein Byte sein kann? Sie würden in der Tat mehrere Bytes Speicher sparen, wenn Sie dies tun.

2. Gleitkommazahlen und Ganzzahlen werden im Computer unterschiedlich gespeichert

Angenommen, wir haben die Nummer 22 in einer ganzen Zahl gespeichert. Der Computer speichert diese Nummer im Binärspeicher wie folgt:

0000 0000 0000 0000 0000 0000 0001 0110

Wenn Sie mit dem Binärzahlensystem nicht vertraut sind, kann dies in wissenschaftlicher Notation dargestellt werden als: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. Das letzte Bit kann verwendet werden oder nicht, um anzuzeigen, ob die Zahl negativ ist (abhängig davon, ob der Datentyp vorzeichenbehaftet oder vorzeichenlos ist).

Im Wesentlichen ist es nur eine Summe von 2 ^ (Bitstelle) * Wert.

Dies ändert sich, wenn Sie sich auf Werte beziehen, die einen Dezimalpunkt enthalten. Angenommen, Sie haben die Dezimalzahl 3,75. Dies wird binär als 11.11 bezeichnet. Wir können dies als wissenschaftliche Notation als 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 oder normalisiert als 1,111 * 2 ^ 2 darstellen

Der Computer kann dies jedoch nicht speichern: Er hat keine explizite Methode, um diesen Binärpunkt auszudrücken (die Binärzahlensystemversion des Dezimalpunkts). Der Computer kann nur Einsen und Nullen speichern. Hier kommt der Gleitkomma-Datentyp ins Spiel.

Angenommen, die Größe von (float) beträgt 4 Bytes, dann haben Sie insgesamt 32 Bit. Dem ersten Bit wird das "Vorzeichenbit" zugewiesen. Es gibt keine nicht signierten Floats oder Doubles. Die nächsten 8 Bits werden für den "Exponenten" verwendet und die letzten 23 Bits werden als "Signifikand" (oder manchmal als Mantisse bezeichnet) verwendet. In unserem Beispiel von 3,75 wäre unser Exponent 2 ^ 1 und unser Signifikant wäre 1,111.

Wenn das erste Bit 1 ist, ist die Zahl negativ. Wenn nicht, positiv. Der Exponent wird durch etwas geändert, das als "Bias" bezeichnet wird, sodass wir "0000 0010" nicht einfach als Exponenten speichern können. Die Vorspannung für eine Gleitkommazahl mit einfacher Genauigkeit beträgt 127, und die Vorspannung für eine doppelte Genauigkeit (hier erhält der doppelte Datentyp seinen Namen) beträgt 1023. Die letzten 23 Bits sind für den Signifikanten reserviert. Der Signifikant ist einfach der Wert rechts von unserem Binärpunkt.

Unser Exponent wäre der Bias (127) + Exponent (1) oder binär dargestellt

1000 0000

Unsere Bedeutung wäre:

111 0000 0000 0000 0000 0000

Daher wird 3,75 dargestellt als:

0100 0000 0111 0000 0000 0000 0000 0000

Betrachten wir nun die Zahl 8, die als Gleitkommazahl und als Ganzzahl dargestellt wird:

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

Wie um alles in der Welt wird der Computer 8.0 und 8 hinzufügen? Oder sogar multiplizieren!? Der Computer (genauer gesagt x86-Computer) verfügt über verschiedene Teile der CPU, die Gleitkommazahlen und Ganzzahlen hinzufügen.

cpmjr123
quelle
3
3) wenn auch selten ein Problem: Operationen mit Zahlen, die größer als die Wortgröße des Computers sind, sind langsamer.
Loren Pechtel
6

Bevor wir Gigabyte-Systeme hatten (oder auf modernen eingebetteten Systemen wie Arduino), war der Speicher knapp und daher wurden Kurzmethoden implementiert, um anzugeben, wie viel Speicher eine bestimmte Anzahl beanspruchen würde - BIT ist unkompliziert - er würde ursprünglich nur 1 Bit belegen der Erinnerung.

Die anderen Datengrößen und -namen variieren zwischen den Systemen. Auf einem 32-Bit-System beträgt INT (oder MEDIUMINT) im Allgemeinen 2 Byte, LONGINT 4 Byte und SMALLINT ein einzelnes Byte. Bei 64-Bit-Systemen kann LONGINT auf 8 Byte eingestellt sein.

Selbst jetzt - insbesondere in Datenbankanwendungen oder Programmen, in denen mehrere Instanzen auf Servern ausgeführt werden (z. B. serverseitige Skripts auf Websites) - sollten Sie bei der Auswahl vorsichtig sein. Die Auswahl einer 2, 4 oder 8 Byte breiten Ganzzahl zum Speichern von Werten zwischen 0 und 100 (die in ein Byte passen können) ist unglaublich verschwenderisch, wenn Sie eine Datenbanktabelle mit Millionen von Datensätzen haben.

Weitere Informationen: https://en.wikipedia.org/wiki/Integer_(computer_science)

HorusKol
quelle
nette Antwort +1.
Vinay
7
Nicht nur "früher", sondern auch "jetzt, wenn ein System klein ist". Auf einem Gerät von der Größe eines Arduino muss man wirtschaftlich sein.
9000
1
Welches System hat nur 1 Bit zum Speichern eines Bits verwendet? Bits sind normalerweise nicht direkt adressierbar
jk.
1
Das gilt für viele Architekturen - aber Bits waren in wirklich alten Systemen direkt adressierbar, und sogar in einigen neueren eingebetteten Systemen (einige Controller, die ich vor 10 Jahren programmiert habe, arbeiteten mit Bits - diese hatten nur ungefähr 64 adressierbare Positionen mit bestimmten Breiten). Heutzutage arbeiten Compiler wohl daran und fügen sie in Byte-Arrays ein.
HorusKol
Ich denke, der übergeordnete Faktor ist eher die CPU-Fähigkeit und -Leistung als die Speicherprobleme
James
4

Zusätzlich zu den hervorragenden Punkten von cpmjr123 in Bezug auf Speicherknappheit, Präzision und Kompromisse bei der Reichweite ist dies möglicherweise auch ein Kompromiss zwischen CPU und CPU.

Die meisten modernen Maschinen verfügen über spezielle Hardware zum Ausführen von Gleitkommaoperationen, die als FPU bezeichnet werden. Es gibt auch Systeme ohne FPUs (heutzutage sind dies normalerweise kleine eingebettete Geräte). Abhängig von Ihrer Zielhardware müssten Sie daher entweder überhaupt keine Gleitkommatypen verwenden oder eine Software-Gleitkomma-Bibliothek verwenden. Selbst wenn Ihr Computer über eine FPU verfügt, gab es in der Vergangenheit Unterschiede in den Funktionen, die er bereitstellen könnte. Alle Funktionen, die nicht in Hardware ausgeführt werden, müssten in Software ausgeführt (oder vermieden) werden.

Das Ausführen von Gleitkommaberechnungen in Software erfolgt durch Ausführen vieler einfacher Operationen, die von der Hardware unterstützt werden. Sie erhalten daher auch einen potenziellen Geschwindigkeitsverlust.

jk.
quelle
4

Das vielleicht wichtigste ist, dass es wirklich drei verschiedene grundlegende Zahlentypen gibt.

Ganzzahl, feste Dezimalstelle und Gleitkomma.

Sie alle verhalten sich unterschiedlich.

Eine einfache Operation wie 7/2 kann je nach verwendetem Datentyp Antworten von 3, 3,50 und 3,499 liefern.

"feste Dezimalzahl" ist der Cinderella-Typ, der nur in einigen Sprachen wie COBOL und VisualBasic nativ unterstützt wird. Für Informatiker ist dies von geringem Interesse, aber für jeden, der eine Reihe von Konten einreicht oder die Umsatzsteuer auf einer Rechnung berechnet, von entscheidender Bedeutung.

James Anderson
quelle
Ich würde sie anders trennen: diskrete Zahlen, ungefähre Zahlen und umhüllende algebraische Ringe. Typische Beispiele in C wäre int, floatund unsigned int, respectively. Festpunkttypen eine Unterkategorie von diskreten Typen sind, aber algebraische Ringe sind grundsätzlich verschieden von Zahlen [muss der Verwirrung in Bezug auf unsigned Typen in C ergibt sich aus der Tatsache , dass sie meist wie Ringe verhalten sich eher als Zahlen, aber nicht ganz konsistent] .
Superkatze
3

Gibt es einen Vorteil, den sie daraus machen?

Na sicher. Es gibt Vorteile. In der Welt der Computer ist der Speicher eines der wichtigsten Dinge, die zu berücksichtigen sind. Was nützt ein Speicher von 2 KB, wenn die Daten in weniger als 1 KB passen? . Optimierungen sollten da sein. Wenn Sie mehr Speicher verwenden, wird die Geschwindigkeit Ihres Computers offensichtlich zu einem bestimmten Zeitpunkt beeinträchtigt. Magst du es wirklich? Kein Recht...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

Nicht nur das Gedächtnis, sondern auch die Art der Zahlen. für eine Instanz Gleitkomma. Die Präzision ist sehr wichtig und natürlich sollten wir einen Typ haben, der uns mehr Präzision geben kann.

Wenn wir alte Tage betrachten, hatten wir, wie Sie vielleicht wissen, ein sehr wenig Gedächtnis. Um es zu speichern und mit Bedacht einzusetzen, hatten wir diese Unterschiede. Und vieles mehr, wenn Sie einfach versuchen, mit Google zu suchen. Ich hoffe, das hilft.

Vinay
quelle
3

Ganzzahlen und reelle (float, double) Zahlen sind konzeptionell unterschiedliche Typen mit unterschiedlichen Operationssätzen und intrinsischen Eigenschaften.

Ganzzahlen sind aufzählbar, Gleitkommazahlen jedoch nicht usw.

Tatsächlich ist Float / Double Number eine Struktur, die zwei ganzzahlige Felder kombiniert: Mantisse und Exponent. Komplexe Zahlen (die Sie von der Betrachtung ausgeschlossen haben) sind noch komplexer.

Jede praktische Sprache sollte mindestens ganze Zahlen und Gleitkommazahlen als unterschiedliche Typen haben - zu unterschiedliche Operationen.

c-smile
quelle
Ich kenne die von Ihnen erwähnten "komplexen Zahlen" nicht. Kannst du es weiter erklären?
cpmjr123
Überprüfen Sie dies: en.wikipedia.org/wiki/Complex_number
c-smile
Mir sind komplexe Zahlen in Form von a + bi bekannt. Ich bat um weitere Informationen darüber, wie der Computer komplexe Zahlen speichert. Meines Wissens gibt es keine primitiven Datentypen, die dies unterstützen.
cpmjr123
Komplexe Zahlen werden typischerweise als zwei Gleitkommawerte gespeichert, nämlich ihr a(Realteil) und b(Imaginärteil). Die CPU implementiert normalerweise keine native Unterstützung für Operationen mit komplexen Zahlen, obwohl die CPU möglicherweise beschleunigte Mehrfachadditionsanweisungen für Operationen mit Wertepaaren wie (a b + c d) und (a b-c d) implementiert .
Rwong
1
Darüber hinaus haben viele Sprachen einige Typen, deren Verhalten weitgehend als das eines umlaufenden algebraischen Rings definiert ist (z. B. wenn eine Variable vom Typ uint16_t65535 enthält, wird sie durch Inkrementieren auf 0 gesetzt). Im Idealfall verfügen Sprachen über sauber getrennte Typen für die Darstellung von umgebenden algebraischen Ringen und Zahlen (wodurch überlaufende Zahlen eingefangen werden können, während Code problemlos Operationen an Dingen ausführen kann, von denen erwartet wird , dass sie umbrochen werden).
Supercat
-1

Zusätzlich zu der Tatsache, dass sich Gleitkommatypen völlig anders verhalten als ganzzahlige Typen, möchte ich ein extremeres Beispiel geben, warum Größe pro Zahl wirklich wichtig ist.

Stellen Sie sich vor, Sie möchten ein (langes) Array sortieren. Zum Beispiel in C:

int numbers[100000000];

Hier haben wir also 100 Millionen Nummern.

Wenn jede Zahl nur ein Byte lang ist (also unsigned charanstelle von int), benötigt dies 100 Millionen Byte Speicherplatz.

Wenn Sie verwenden double, sind dies normalerweise 8 Bytes pro Nummer, also 800 Millionen Bytes Speicherplatz.

Jedes Mal, wenn Sie mit vielen Objekten arbeiten (Zahlen in diesem Beispiel), spielt die Größe pro Objekt (Größe pro Zahl in diesem Beispiel) wirklich eine Rolle.

Ingo Blackman
quelle