Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stream over a range of BigIntegers?

Hello I currently have this piece of code for finding factorial which is work fine

public static BigInteger factorial(BigInteger n) {
    BigInteger sum = BigInteger.ONE;
    for (BigInteger i = BigInteger.ONE; i.compareTo(n) <= 0; i = i.add(BigInteger.ONE)) {
        sum = sum.multiply(i);
    }
    return sum;
}

What I want to achieve is to convert this to a Stream<BigInteger> and write it like this

public static BigInteger factorial(BigInteger n) {
    return getBigIntegerStream(n).reduce(BigInteger.ONE, BigInteger::multiply);
}

So my question is how I can get a Stream<BigInteger> similar to how I can declare an IntStream?

IntStream.range(1, myInt);
like image 875
Panos K Avatar asked Jul 10 '19 09:07

Panos K


People also ask

What is range of BigInteger?

BigInteger must support values in the range -2 Integer.MAX_VALUE (exclusive) to +2 Integer.MAX_VALUE (exclusive) and may support values outside of that range. The range of probable prime values is limited and may be less than the full supported positive range of BigInteger . The range must be at least 1 to 2500000000.

How do you compare big integer values?

math. BigInteger. equals(Object x) method compares this BigInteger with the object passed as the parameter and returns true in both are equal in value else it returns false. Parameter: This method accepts a single mandatory parameter x which is the Object to which BigInteger Object is to be compared.

What is the max value of BigInteger in Java?

Given that it is a signed data type, this gives it the range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

What is BigInteger one?

BigInteger. An object whose value is one (1).

What is the difference between BigInteger andnot and BigInteger and (BigInteger Val)?

BigInteger and (BigInteger val): This method returns a BigInteger whose value is (this & val). BigInteger andNot (BigInteger val): This method returns a BigInteger whose value is (this & ~val). int bitCount (): This method returns the number of bits in the two’s complement representation of this BigInteger that differ from its sign bit.

What is the use of BigInteger in Java?

BigInteger Class in Java Last Updated: 20-05-2019 BigInteger class is used for mathematical operation which involves very big integer calculations that are outside the limit of all available primitive data types. For example factorial of 100 contains 158 digits in it so we can’t store it in any primitive data type available.

What is the upper bound of the range of integers?

There is no theoretical limit on the upper bound of the range because memory is allocated dynamically but practically as memory is limited you can store a number which has Integer.MAX_VALUE number of bits in it which should be sufficient to store mostly all large values. Below is an example Java program that uses BigInteger to compute Factorial.

How to convert a BigInteger to a float value?

BigInteger flipBit (int n): This method returns a BigInteger whose value is equivalent to this BigInteger with the designated bit flipped. float floatValue (): This method converts this BigInteger to a float. BigInteger gcd (BigInteger val): This method returns a BigInteger whose value is the greatest common divisor of abs (this) and abs (val).


2 Answers

The equivalent would be

Stream.iterate(BigInteger.ONE, i -> i.add(BigInteger.ONE))
    .takeWhile(i -> i.compareTo(end) < 0)

where end is a BigInteger.

Stream.iterate will create an infinite stream, starting from 1 and continually adding 1. takeWhile will stop the stream once the condition is met.

like image 125
Michael Avatar answered Sep 24 '22 21:09

Michael


Perhaps something like this:

public static BigInteger factorial(BigInteger n) {
    return Stream.iterate (BigInteger.ONE, i -> i.add(BigInteger.ONE)).limit(Integer.parseInt(n.toString())).reduce(BigInteger.ONE, BigInteger::multiply);
}

EDIT: I forgot to limit the stream. Fixed now.

Of course it would be simpler to just accept an int (or a long) as the argument:

public static BigInteger factorial(int n) {
    return Stream.iterate (BigInteger.ONE, i -> i.add(BigInteger.ONE)).limit(n).reduce(BigInteger.ONE, BigInteger::multiply);
}

It is very unlikely you will even need to calculate the factorial of a number larger than Integer.MAX_VALUE. The factorial of such a number would be huge, and would probably take very long to calculate.

EDIT: Not a proper benchmark, but factorial(100000) took me 5 seconds, and factorial(1000000) took 8 minutes. At this rate, factorial(Long.MAX_VALUE) or even factorial(Integer.MAX_VAULE) will take very very long time. Therefore I don't see the point of requiring a BigInteger argument.

like image 20
Eran Avatar answered Sep 22 '22 21:09

Eran