The following function will accept an integer number as input and will produce an IntStream
, which is a sequence of primitive int-valued elements that supports sequential and parallel aggregate operations.
public static IntStream splitToPowersOfTwo(final int input) { int temp = input; final IntStream.Builder builder = IntStream.builder(); while (temp != 0) { //Integer.lowestOneBit: Finds the lowest-order ("rightmost") one-bit in the specified int value and returns an int number that has only the bit in the previously matched position set as 1. This value is a power of two that is one of the components of the number. If the number is zero, the function returns zero. final int powerOfTwo = Integer.lowestOneBit(temp); builder.add(powerOfTwo); //We update our temp by subtracting the number we got, our goal is to remove the previously matched bit and get the next one on the next iteration. temp = temp & ~ powerOfTwo; } return builder.build(); }
We used Integer.lowestOneBit
as it makes it easy for us to breakdown the number to its power of two components by matching for us only one bit at time.
Example of usage:
Scenario: We want to breakdown an integer to the powers of two that their sum produces the number and create a String with those values. Using our function, we can do the following:
final String output = splitToPowersOfTwo(flags).mapToObj(Integer::toString).collect(Collectors.joining(", "));
Note: an IntStream
is not the same as a Stream<Integer>
, we used .mapToObj(Integer::toString)
which calls the static method Integer.toString(int)
. This is different to calling .map(Integer::toString)
on a Stream<Integer>
as the latter won’t compile because it is ambiguous.
This post is also available in: Greek
This code will NOT convert the number to Base 2. It will return a stream of base 10 numbers that if you sum them up, will return the original value.
For the number 25 (base 10) it will create a stream of numbers (also base 10). The stream will contain the values [1, 8, 16].