Warum ist BigInteger kein Primitiv?

8

Wenn Sie BigInteger (oder BigDecimal ) verwenden und sie arithmetisch ausführen wollen, müssen Sie beispielsweise die Methoden add oder subtract verwenden. Das mag gut klingen, bis Sie merken, dass dies

ist %Vor%

würde für BigInteger :

so geschrieben werden %Vor%

Wie Sie sehen können, ist es etwas einfacher, die erste Zeile zu lesen. Dies könnte gelöst werden, wenn Java das Überladen von Operatoren zulässt, dies aber nicht tut, so wirft dies die Frage auf:

Warum ist BigInteger kein primitiver Typ, so dass er die gleichen Operatoren wie andere primitive Typen nutzen kann?

    
Frozendragon 26.02.2015, 15:19
quelle

5 Antworten

16

Das liegt daran, dass BigInteger tatsächlich nichts ist, was nahe daran liegt, ein Primitiv zu sein. Es wird unter Verwendung eines Arrays und einiger zusätzlicher Felder implementiert, und die verschiedenen Operationen umfassen komplexe Operationen. Zum Beispiel, hier ist die Implementierung von add :

%Vor%

Primitive in Java sind Typen, die normalerweise direkt von der CPU des Host-Rechners implementiert werden. Zum Beispiel hat jeder moderne Computer einen Maschinensprachbefehl für die Ganzzahladdition. Daher kann es auch sehr einfachen Byte-Code in der JVM haben.

Ein komplexer Typ wie BigInteger kann normalerweise nicht so behandelt werden und kann nicht in einfachen Byte-Code übersetzt werden. Es kann kein Primitiv sein.

Ihre Frage könnte also lauten "Warum kein Operator in Java überlastet wird". Nun, das ist Teil der Sprachphilosophie.

Und warum nicht eine Ausnahme machen, wie für String ? Denn nicht nur ein Operator ist die Ausnahme. Sie müssen eine Ausnahme für die Operatoren * , / , + , - , << , ^ und so weiter machen. Und Sie haben immer noch einige Operationen im Objekt selbst (wie pow , die nicht von einem Operator in Java repräsentiert werden), die für Grundelemente von Spezialklassen behandelt werden (wie Math ).

    
RealSkeptic 26.02.2015, 15:32
quelle
5

Grundlegend, weil die informelle Bedeutung von "primitiv" ist, dass es Daten sind, die direkt mit einer einzigen CPU-Anweisung . Mit anderen Worten, sie sind Primitive, weil sie in ein 32- oder 64-Bit-Wort passen, welches die Datenarchitektur ist, mit der Ihre CPU arbeitet, so dass sie explizit in der registriert .

Und so kann Ihre CPU folgende Operation ausführen:

%Vor%

Ein BigInteger, der eine beliebig große Menge an Speicher belegen kann, kann nicht in einem einzelnen REGISTER gespeichert werden und muss mehrere Anweisungen ausführen, um eine einfache Summe zu erstellen.

Dies ist der Grund, warum möglicherweise kein primitiver Typ sein kann, und jetzt sind sie tatsächlich Objekte mit Methoden und Feldern, eine viel komplexere Struktur als einfache primitive Typen.

Hinweis: Der Grund, warum ich diese informelle genannt habe, ist, weil die Java-Entwickler letztendlich einen "primitiven Java-Typ" definieren könnten, sie besitzen das Wort, jedoch ist dies vage die vereinbarte Verwendung des Wortes.

    
DSquare 26.02.2015 15:35
quelle
2

int und boolean und char sind keine Primitive, so dass Sie Operatoren wie + und / nutzen können. Sie sind primitive aus historischen Gründen, von denen die größte Leistung ist.

Primitive sind in Java nur solche Dinge, die keine vollwertigen Objekte sind. Warum sollten Sie diese ungewöhnlichen Strukturen erstellen (und diese dann später als richtige Objekte implementieren, wie zum Beispiel Integer )? Hauptsächlich für die Leistung: Operationen auf Objekte waren (und sind) langsamer als Operationen auf primitiven Typen. (Wie andere Antworten erwähnen, machte die Hardware-Unterstützung diese Operationen schneller, aber ich würde nicht zustimmen, dass Hardware-Unterstützung eine "essentielle Eigenschaft" von Primitiven ist.)

Einige Typen erhielten also "spezielle Behandlung" (und wurden als Primitive implementiert) und andere nicht. Stellen Sie sich das so vor: Wenn selbst das sehr beliebte String kein primitiver Typ ist, warum sollte BigInteger sein?

    
mk. 26.02.2015 15:24
quelle
1

Es liegt daran, dass primitive Typen eine Größenbeschränkung haben. Zum Beispiel ist int 32 Bits lang und 64 Bits lang. Wenn Sie also eine Variable vom Typ int erstellen, ordnet die JVM dafür 32 Bit Speicher auf dem Stack zu. Aber wie für BigInteger, hat es "theoretisch" keine Größenbeschränkung. Das bedeutet, dass es beliebig groß werden kann. Aus diesem Grund gibt es keine Möglichkeit, seine Größe zu kennen und dafür einen festen Speicherblock auf dem Stapel zuzuordnen. Daher wird es auf dem Heap zugewiesen, wo die JVM die Größe bei Bedarf immer erhöhen kann.

    
Anwuna 26.02.2015 15:38
quelle
0

Primitive Typen sind in der Regel historische Typen von Prozessorarchitektur definiert. Weshalb Byte 8-Bit ist, kurz ist 16-Bit, 32-Bit-int ist und lang ist 64-Bit. Vielleicht, wenn es mehr 128-Bit-Architekturen ist, wird eine zusätzliche primitive erstellt wird ... aber ich kann nicht dort sehen ist genug Antrieb für diese ...

    
mixmastered 26.02.2015 15:31
quelle

Tags und Links