import java.util.Scanner;
import java.util.Arrays;
import java.util.*;

public class Main
{
    public static void main(String[] args) 
    {
        int binaryWidth=32;
        int num;  //user input
        int num1; //user input
        test t;  //instance variable of type test
        
        Scanner reader = new Scanner(System.in); // Reading from System.in
        System.out.println("Enter a number no larger than: " + Math.pow(2,binaryWidth));
        num = reader.nextInt(); // Scans the next token of the input as an int.
        
        do
        {
            System.out.println("Enter a number no larger than: " + Math.pow(2,binaryWidth));
            num1 = reader.nextInt(); // Scans the next token of the input as an int.
            
        } while (num1<num);  //to ensure that a range can be processed...
        
        //once finished
        reader.close();
        
        // this is to ensure the size of array to store decimals and binary conversions
        // is inclusive of the lower and upper limit
        int sizeArray = (num1-num)+1;  // this is correct...
        
        System.out.println("Array to be created of size: " + sizeArray + " to hold decimals");
        System.out.println("Array to be created of size: " + sizeArray + " to hold decimals in binary form");
        System.out.println("\n");

        // instantiation START here
        t= new test(num,num1,sizeArray);
        
    }
    
}

class test
{
    int binaryWidth=32;
    
    int binary[] = new int[binaryWidth];
    
    //This holds the binary value
    //It is 32 bits wide... as you typically see in real world.....
    //However not using octets since this is associated with IP addresses....
    //2,147,483,648 is well within Java's limit...
    //Also need to ensure end user does not select an upper bound greater than this.....

    int j; //counter
    int i; //counter
    String conversion; // this will be used to output binary conversion on screen without having to iterate through loop again
    int num;  //user input
    int sizeArray;   //range between user inputs...
    int num1;  //user input
    int pos;  //index to store the 1 for decimal => binary conversion..
    
    int [][]binaryRepository;  //need a 2D array due to processing as below....
    
    int k=0;
    boolean setBitOff=false;  //used to check if a 0 appears in same position of the number range selected by end user.
    
    //performs bitwise and of all the binary conversions....
    // 1 AND 1 = 1    All other scenarios are 0
    
    /*
        // to do this need to go down the columns and perform BitWise and..
        //if at any point a 0 is found, it will set bit to 0.
        [0]          [0]      [0][1]                [0][binaryWidth-1   = 31]
        [1]          [0]      [1] [1]
        [2]          [0]      [2] [1]
        [sizeofArray][0]      [sizeofArray][1]
        */
    
    public void bitWiseAnd()
    {
        int[] bitWiseAndOutcome = new int[binaryWidth];  //this will be final outcome, this is a 1D array.
        
        //this is going through the length (columns) of the binary number in 32bit format
        for (int k=0; k<binaryWidth;k++)
        {
            System.out.println("Processing " + k + " bit");
            
        //for each column, it needs to check same position on each row...
        //numbers rows is sizeArray
        //ths is going through each row in the 2D array of binaryRepository    
        for (int i=0; i<sizeArray; i++)
        {
            // if there is a zero
            if (binaryRepository[i][k]==0)
            {
                System.out.println("0 bit found in column");
                
                //off bit is identified as 0.... Flag set to true
                setBitOff=true;
                
                //if its not on the last bit of the binary, informs end user moving to next bit
                if (k!=binaryWidth-1)
                {
                    System.out.println("Moving onto bit: " + (k+1));
                }
            }
            
            //if a 0 is found whilst moving downwards     1,    1,  0,  0     
            //                                            0(X), 1,  0,  0
            //this will set bitwise AND bit as 0
            
            if (setBitOff)
            {
                
                bitWiseAndOutcome[k]=0;
                
                //safe option instead of break and continue;
                //this will ensure that the next bit on the binary number will be compared immediately....
                i=sizeArray;
            }
            
            //this circumstance can only be true if it has gone through entire column and all are 1s
            //1,    0,  0,  0
            //1,    1,  0,  0     
            //1(X), 1,  0,  0
            
            else
            {
                bitWiseAndOutcome[k]=1;
                System.out.println("All 1s found in column");
            }
    
        } // end of for loop to move across all rows in binaryRepository(which contains all binary conversions)
        
        //the flag is turned to false, since its ready to start at next bit..
        setBitOff=false;
    }  //end for  - moving through all bits in binary number. 
        
        System.out.println("\nThis is bitwise And of the selected range of decimals:\n " + Arrays.toString(bitWiseAndOutcome));
        
    }
    
    public test(int num, int num1, int sizeArray)
    {
        this.sizeArray=sizeArray;
        this.num=num;
        this.num1=num1;
        int rangeDecimal[] = new int[sizeArray]; // this will hold all the decimal values to be converted
        binaryRepository = new int[sizeArray][binaryWidth];
        
        // This is to store all decimal numbers into array
        for (int i=0; i<sizeArray;i++)    //if sizeofarray is 3 for instance lower=2  upper =4
        {
            // if range was 3-5 (user input),   i would range from 0, 1, 2
            //the first decimal  3  would be stored at  rangeDecimal[0] = 3+0  = 3
            //the second decimal  4  would be stored at  rangeDecimal[1] = 3+1 = 4
            //the third decimal  5  would be stored at  rangeDecimal[2] = 3+2  = 5 
            
            rangeDecimal[i]=num+i;
            System.out.println("\n");
          
            System.out.println("The decimal number is: " + rangeDecimal[i]);
    
            //binary is a single dimensional array, so length is ok....
            int length = binary.length;
            System.out.println("*** This program will convert decimal " + rangeDecimal[i]+ " into binary");
            
            //Execute a for loop to check modulus (i.e no remainder)
            //since its zero index
            //also similar to the real world when doing conversions, the divisor has to be largest 2^j
            
            //it will go through 0-31   2^31 to 2^0
            for (j=(length-1); j>=0; j--)
            {
                //starts from 2^31 to 2^0 
                int divisor = (int)(Math.pow(2,j));
                
                //if the binary divisor fits in the decimal
                if (rangeDecimal[i] - divisor >=0)
                {
                    //we know the end of the binary array is binary[length -1]
                    //j starts from binaryWidth-1 (31) to 0       (due to zero indexing)
                    //if the divisor fits into the remaining decimal, it inputs a 1.
                    
                    //so if it is found divisor 16 for instance is divisible in number, j would be 27
                    
                    //[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0]
                    //binary[31-27] =1    binary[4]=1
                    
                    //if it found the first divisor is divisble in number, j would be 31
                    //binary[31]
                    
                    //We know numbers in binary array are called back from binary[0] => binary[31]
                    pos =  ((length-1)-j);
                    
                    binary[pos] = 1;  // we know this is correct since conversions are fine!!
                    
                    
                    //pos would be the column in context of 2D array..
                    //i would be the row....
                    binaryRepository[i][pos] = 1;
                    
                    //this is remainder of decimal once the binary divisor has been subtracted...
                    rangeDecimal[i]=rangeDecimal[i]-divisor;
                }
                else
                {
                    
                }
                
            }
            conversion = Arrays.toString(binary);
            System.out.println("Decimal is: " + (num+i));
            System.out.println("The binary version is : " + conversion );
            conversion=Arrays.toString(binaryRepository[i]);
            System.out.println("The binary in array is: " + conversion);
            
            //re-initialises the integer array.... This was my failing point previously whilst coding..
            binary=new int[binaryWidth];
        }
        //performing bitWiseAnd
        bitWiseAnd();
        
    }
}