Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't BigInteger a primitive

If you use BigInteger (or BigDecimal) and want to perform arithmetic on them, you have to use the methods add or subtract, for example. This may sound fine until you realize that this

 i += d + p + y;

would be written like this for a BigInteger:

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

As you can see it is a little easier to read the first line. This could be solved if Java allowed operator overloading but it doesn't, so this begs the question:

Why isn't BigInteger a primitive type so it can take advantage of the same operators as other primitive types?

like image 974
Icy Creature Avatar asked Feb 26 '15 15:02

Icy Creature


People also ask

What is the difference between integer and BigInteger?

The int data type is the primary integer data type in SQL Server. The bigint data type is intended for use when integer values might exceed the range that is supported by the int data type. bigint fits between smallmoney and int in the data type precedence chart.

Is BigInt the same as long Java?

The equivalent of Java long in the context of MySQL variables is BigInt. In Java, the long datatype takes 8 bytes while BigInt also takes the same number of bytes.

What is the difference between BigInteger and integer in Java?

BigInteger represents immutable arbitrary-precision integers. It is similar to the primitive integer types but allows arbitrary large values. It is used when integers involved are larger than the limit of long type. For example, the factorial of 50 is 30414093201713378043612608166064768844377641568960512000000000000.

What is difference between BigInt and long?

BigInteger Class. As we know, the BigInteger class is used for mathematical operations which involve very big integer calculations larger than the primitive long type. It represents immutable arbitrary-precision integers.


2 Answers

That's because BigInteger is not, in fact, anything that is close to being a primitive. It is implemented using an array and some additional fields, and the various operations include complex operations. For example, here is the implementation of add:

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 CPU of the host machine. For example, every modern computer has a machine-language instruction for integer addition. Therefore it can also have very simple byte code in the JVM.

A complex type like BigInteger cannot usually be handled that way, and it cannot be translated into simple byte code. It cannot be a primitive.


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


And why not make an exception, like for String? Because it's not just one operator that is the exception. You need to make an exception for the operators *, /, +,-, <<, ^ and so on. And you'll still have some operations in the object itself (like pow which is not represented by an operator in Java), which for primitives are handled by speciality classes (like Math).

like image 79
RealSkeptic Avatar answered Sep 21 '22 19:09

RealSkeptic


Fundamentally, because the informal meaning of "primitive" is that it's data that can be handled directly with a single CPU instruction. In other words, they are primitives because they fit in a 32 or 64 bits word, which is the data architecture that your CPU works with, so they can explicitely be stored in the registers.

And thus your CPU can make 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 can't be stored in a single REGISTER and will need to perform multiple instructions to make a simple sum.

This is why they couldn't possibly be a primitive type, and now they actually are objects with methods and fields, a much more complex structure than simple primitive types.

Note: The reason why I called this informal is because ultimately the Java designers could define a "Java primitive type" as anything they wanted, they own the word, however this is vaguely the agreed use of the word.

like image 27
DSquare Avatar answered Sep 20 '22 19:09

DSquare