Aman Singh
Aman Singh

Reputation: 57

The constructor BigInteger(long) is not visible

So I'm creating a factorial program using BigInteger class. But I keep getting the above error.

public static BigInteger fact(long n){
        BigInteger result = BigInteger.ONE;
        for(int i = 1; i <= n; ++i){
            result = result.multiply(new BigInteger(i));
        }
        return result;
}

I already found the fix which is just add an empty string with result.

result = result.multiply(new BigInteger(i + ""))

My question is, why do we have to add that empty string ?

Upvotes: 4

Views: 7119

Answers (6)

GauravJ
GauravJ

Reputation: 2262

BigInteger constructor with long is private because the library developer wants you to invoke BigInteger.valueOf(long l). The reason why constructor is private is provided in javadoc of valueOf,

Returns a BigInteger whose value is equal to that of the specified {@code long}. This "static factory method" is provided in preference to a ({@code long}) constructor because it allows for reuse of frequently used BigIntegers.

Upvotes: 2

Piyush Aghera
Piyush Aghera

Reputation: 965

It is showing the correct error. If you look at the BigInteger class in the documentation, then you can see that there is no constructor that accepts an int. So you can't create BigInteger object by using new and passing an int.

There is a constructor that accepts a string, and by adding an empty string, you are casting your int to string.

You can use the following code:

int myint = 5; // For example
BigInteger myBigInter = BigInteger.valueOf(myint);

Upvotes: 2

sobrino
sobrino

Reputation: 153

BigInteger has no constructor that accepts int. By adding an empty string, i is converted to a String.

You could also do something like new BigInteger(String.valueOf(i))

Edit: Why do you have to use a String? BigInteger is (usually) used if you need bigger values than Integer.MAX_VALUE or even Long.MAX_VALUE. So, if you want to create a BigInteger that holds a value greater than that, you need to pass it as an object/variable that can hold that value. And a String is able to hold it.

Upvotes: 0

2rd_7
2rd_7

Reputation: 472

123+"" is same as Integer.toString(123)+"" i.e adding an empty string to an integer is converting that integer to string.

And as per docs BigInteger has a constructor that takes the decimal string of an integer as an argument.

And as mentioned by SpringLearner BigInteger doesn't have a constructor that takes just int as an argument.

Upvotes: 1

jarjar
jarjar

Reputation: 379

When you add an empty string to your constructor parameter, the java compiler transform your parameter to string : 5 + "" -> "5". the resulting consequence is java will use the BigInterger constructor with String parameter. This is why your code works.

 /**
     * Translates the decimal String representation of a BigInteger into a
     * BigInteger.  The String representation consists of an optional minus
     * sign followed by a sequence of one or more decimal digits.  The
     * character-to-digit mapping is provided by {@code Character.digit}.
     * The String may not contain any extraneous characters (whitespace, for
     * example).
     *
     * @param val decimal String representation of BigInteger.
     * @throws NumberFormatException {@code val} is not a valid representation
     *         of a BigInteger.
     * @see    Character#digit
     */
    public BigInteger(String val) {
        this(val, 10);
    }

So to use a clean code use this :

new BigInteger(Integer.toString(i), 10)

Upvotes: 1

SpringLearner
SpringLearner

Reputation: 13844

As per oracle docs, BigInteger does not have any constructor that takes int as an argument

Secondly you should use BigInteger.valueOf(i); instead of new BigInteger(i + "")

Upvotes: 15

Related Questions