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

public class Main
{
    public static void main(String[] args) 
    {
        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,32));
        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,32));
            num1 = reader.nextInt(); // Scans the next token of the input as an int.
            
        } while (num1<num);
        
        //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 binary[] = new int[32];
    
    //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[] bitWiseAndOutcome = new int[sizeArray];  //this will be final outcome, this is a 1D array.
    
    int k=0;
    boolean setBitOff=false;
    
    public void bitWiseAnd(int [][]binaryRepository)
    {
        //ths is going through each row in the 2D array of binaryRepository
        for (int i=0; i<sizeArray; i++)
        {
            //if it has reached the last row of the column, it has to increase checking to the next column....
            if (i==sizeArray-1)
            {
                k++;
            }
            
            if (binaryRepository[i][k]==0)
            {
                System.out.println("Value bit at" + k +":" + binaryRepository[i][k]);
                
                setBitOff=true;
            }
            
            if (setBitOff)
            {
                System.out.println("value of i: " + i);
                
                bitWiseAndOutcome[i]=0;
            }
            else
            {
                bitWiseAndOutcome[i]=1;
            }
            
            setBitOff=false;
        }
        
        System.out.println("This is bitwise And of the selected range of decimals: " + Arrays.toString(bitWiseAndOutcome));
        
        /*
        // 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][31]
        [1]          [0]      [1] [1]
        [2]          [0]      [2] [1]
        [sizeofArray][0]      [sizeofArray][1]
        */
    }
    
    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][32];
        
        // 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
        {
            //from num to num1  will be sizeArray
            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 31 to 0
                    //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;
                    
                    
                    binaryRepository[i][pos] = 1;
                    
                    //this is remainder of decimal once the binary divisor has been subtracted...
                    rangeDecimal[i]=rangeDecimal[i]-divisor;
                }
                else
                {
                    binaryRepository[i][pos] = 0;
                }
                
            }
            conversion = Arrays.toString(binary);
            System.out.println("Decimal is: " + (num+i));
            System.out.println("The binary version is: " + conversion );
            
            //it needs to be a 2D since its a repository of all binary conversions....
            // i will increment through sizeArray (lower - upper bound decimal range inclusive defined end user...)
            //=binary;
            //re-initialises the integer array....
            
            binary=new int[32];
        }
        bitWiseAnd(binaryRepository);
        
    }
}
