Why BigInteger is not primitive

If you use BigInteger (or BigDecimal ) and want to perform arithmetic on them, you should, for example, use the add or subtract methods. It may sound normal until you understand that it

  i += d + p + y; 

It will be written like this::

  i = i.add(d.add(p.add(y))); 

As you can see, the first line is a little easier to read. This can be resolved if Java allows operator overloading, but it is not, so the question is:

Why is there no BigInteger primitive type so that it can use the same operators as other primitive types?

+8
java biginteger primitive
source share
5 answers

This is because BigInteger is not really close to being primitive. It is implemented using an array and some additional fields, and various operations include complex operations. For example, here is the add implementation:

 public BigInteger add(BigInteger val) { if (val.signum == 0) return this; if (signum == 0) return val; if (val.signum == signum) return new BigInteger(add(mag, val.mag), signum); int cmp = compareMagnitude(val); if (cmp == 0) return ZERO; int[] resultMag = (cmp > 0 ? subtract(mag, val.mag) : subtract(val.mag, mag)); resultMag = trustedStripLeadingZeroInts(resultMag); return new BigInteger(resultMag, cmp == signum ? 1 : -1); } 

Primitives in Java are types that are usually implemented directly by the processor of the host machine. For example, every modern computer has a machine language instruction for integer additions. Therefore, it can also have very simple byte code in the JVM.

A complex type such as BigInteger cannot usually be processed this way and cannot be translated into simple byte code. This cannot be primitive.


So your question might be "Why is there no operator overloading in Java". Well, that part of the philosophy of language.


And why not make an exception, for example, for String ? Because this is an exception not only from one operator. You must make an exception for the operators * , / , + , - , << , ^ and so on. And you still have some operations in the object itself (for example, pow , which is not represented by an operator in Java), which for primitives is handled by special classes (for example, Math ).

+16
source share

Basically, since the unofficial meaning of "primitive" is that data can be processed directly with a single CPU command. In other words, they are primitives because they correspond to a 32 or 64 bit word, which is the data architecture your processor works with, so they can be explicitly saved to Cash registers .

Thus, your processor can perform the following operation:

 ADD REGISTER_3 REGISTER_2 REGISTER_1 ;;; REGISTER_3 = REGISTER_1 + REGISTER_2 

A BigInteger, which can occupy an arbitrarily large amount of memory, cannot be stored in one REGISTER, and to execute a simple amount, you will need to follow several instructions.

That is why they cannot be a primitive type, and now they are actually objects with methods and fields, a much more complex structure than simple primitive types.

Note. The reason I called it informal is because in the end, Java developers could define the "primitive Java type" as everything they wanted, they own the word, but this is a vaguely consistent use of the word.

+5
source share

int and boolean and char are not primitives, so you can use operators such as + and / . They are primitive for historical reasons, the largest of which is performance.

In Java, primitives are defined as only those things that are not fully functional objects. Why create these unusual structures (and then re-execute them as the right objects, like Integer , later)? First of all, for performance: operations on objects were (and) slower than operations on primitive types. (As mentioned in other answers, hardware support accelerated these operations, but I would not agree that hardware support is an “essential property” of primitives.)

So, some types received "special treatment" (and were implemented as primitives), while others did not. Think of it this way: even if the wildly popular String not a primitive type, why should BigInteger be?

+2
source share

This is because primitive types have a size limit. For example, int is 32 bits and 64 bits long. Therefore, if you create an int variable, the JVM allocates 32 bits of memory on the stack for it. But as for BigInteger, it “theoretically” has no size limit. This means that it can grow arbitrarily in size. Because of this, there is no way to find out its size and allocate a fixed block of memory for it for the stack. Therefore, it stands out on the heap, where the JVM can always increase size if necessary.

+1
source share

Primitive types are usually historical types defined by processor architecture. This is why the byte is 8-bit, short is 16-bit, int is 32-bit and long is 64-bit. Maybe when another 128-bit architecture appears, an additional primitive will be created ... but I don’t see that there is enough disk for this ...

0
source share

All Articles