CSCI 255 — Bits in C and Java

The goal of this lab is to introduce you to the bit operators of Java, C, C++, JavaScript, Python, … These are the same logical operations we will be using in our circuit designs.

We’re going to use NetBeans because, later in the course, we’ll use the MPLAB® X IDE which is based on NetBeans.

If you haven’t used NetBeans before, try to sit close to someone who has. And plan on staying a little longer in the lab.

Starting NetBeans

First, start NetBeans. If your account was freshly created for this course, you are in luck. There’s a launcher on the left side of the screen for NetBeans.

If you have an old account, you’ll need to create a launcher. This involves docking /usr/local/share/applications/netbeans-8.0.desktop onto your screen. Figuring this out requires an Ubuntu guru. Better find one.

Printing powers with Java

From NetBeans, create a project called Powers, using the menu choices FilesNew Project. At the New Project window select the project type Java Application and then press Finish.

Delete as many of the built-in comments as you want. Before the main method add the following additional method which receives a single integer argument and prints a list of the powers of that argument.

    static void printPowers(int i) {
        int p = 1 ;
        while (p*i>0) {     /* This fails on overflow */
            System.out.println(p) ;
            p *= i ;        
        }
    }

We really must call printPowers, so add the following three invocations inside the main method.

    printPowers(2) ;
    printPowers(6) ;
    printPowers(10) ;

Run the program and look at the output. You’ll notice something rather odd about the last printed line. This is an artifact of a multiplication resulting in a number too big to store in a Java integer. That’s a topic for next week’s lecture.

Notice how sloppy those output lines are! We need to straighten them up a little. This is a job for a feature passed down from FORTRAN to C to Java, formatted I/O.

Replace the call to System.out’s println method with a call to its printf method.

       System.out.printf("%20d  %35s\n", p, Integer.toBinaryString(p)) ;

On the right is a call to the static method Integer.toBinaryString which generates an almost-appropriate string of 1’s and 0’s for an integer. In the middle is the format specifier which is explained in the Java documentation of the format string syntax. It’s a good idea to master C-style format specifiers. They appear in many programming languages.

Once you’ve made this change, you should be able to run your program and get some pretty nice output; except for those missing 0’s at the beginning of the binary string. (Those can be fixed with Integer.toBinaryString(p).replace(' ', '0') . Ugh.)

Using Java’s bitwise operators

Now we’re going to use a few Java operators that you are unlikely to encounter in an introductory programming classes. Start by creating a new NetBeans project called BitOps. Just accept the defaults.

You can’t do serious testing without data and the easiest way to get data is with random number generators. Start by adding the following line before the class definition.

import java.util.Random;

Next add the following code inside the main method.

        Random gen = new Random() ;
        for(int i=0; i<10; ++i) {
            int a = gen.nextInt() ;
            int b = gen.nextInt() ;
            System.out.printf("%s  %s\n",
                    Integer.toBinaryString(a),
                    Integer.toBinaryString(b)) ;
	}

The call of the Random constructor creates and seeds a random number generator. The calls of its nextInt method generates a sequence of random numbers. Go ahead and run your program.

Those numbers are random and pretty hard to read. Instead of printing binary numbers, we should print hexadecimal numbers. Hexadecimal numbers are in base 16. One hexadecimal digit can take the place of four binary digits. Hexadecimal numbers are a convenient way of expressing long binary strings. That’s why they are used to write the MEID that identifies your cell phone.

hexadecimal 0 1 2 3 4 5 6 7 8 9 A B C D E F
decimal 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
binary 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

Let’s replace that those binary strings with some hex. And, while we’re at it, let’s print a little list of the results of adding those pairs of random numbers. The output may look puzzling, but there are some people add hexadecimal numbers almost as well as you add decimal numbers. Notice that the format specifier provides a special conversion specifier for hex.

            System.out.printf("%08X  %08X\n", a, b) ;
            System.out.printf("ADD(%08X,%08X) -> %08X\n", a, b, a+b) ;

Run your program and verify at least one of these additions. Remember 9+5=E and A+7=11.

You’ve used Java’s boolean operators, &&, || and ! in 181 or 182. Java also has three corresponding bitwise operators, &, | and ~, that can be applied to integers. In the bitwise operators, the bits of the integer pretend to be boolean values: 1 plays the role of true and 0 plays the role of false. By the way, C++, JavaScript, and Python have these same three operations which first appeared in C.

Add the following lines to your program to see the result of applying these operators. Again, be sure to verify the result of at least one application of each of the three.

            System.out.printf("AND(%08X,%08X) -> %08X\n", a, b, a&b) ;
            System.out.printf(" OR(%08X,%08X) -> %08X\n", a, b, a|b) ;
            System.out.printf("NOT(%08X)          -> %08X\n", a, ~a) ;
            System.out.println() ;

C, C++, Java, JavaScript, and Python also have three shifting operators. These allow the bits of an integer to be moved left and right. In C and C++ these are written as << for right shift and >> for left shift. Java and JavaScript have an additional >>> left shift operator which we will someday be explained in class.

It’s time to add some shifty operators to your program.

            int sb = b & 31 ;         /* No more than 31 */
            System.out.printf("SHL(%08X,%2d)       -> %08X\n", a, sb, a>>>sb) ;
            System.out.printf("SHR(%08X,%2d)       -> %08X\n", a, sb, a<<sb) ;

There are a bit harder to verify, but do make a try. Start with one where the shift offset (sb), is divisible by four. You’ll soon see why this is a good idea.

Let’s end the section with one final real-life example. Every time an IP (Internet Protocol) packet is received, its IP header must be examined. These happens gazillions of times every day.

Here is a couple of lines of Java that “look” at 32-bits that could be an IP header and print the length of the packet and header. Try them out and then learn to admire what they do.

            System.out.printf("PKTLEN(%08x)       -> %08x\n", a, a&0xFFFF) ;
            System.out.printf("HDRLEN(%08x)       -> %08x\n", a, (a>>24)&0xF) ;

Becoming a C and C++ guru

Now we are going to write some C and C++. It won’t be as hard as you think. Start by creating a new NetBeans project. At the New Project menu create a C/C++ application within the C/C++ category.

You will need to use the little arrow on the side to specify that you are creating a C, rather than C++ or FORTRAN, application.
Choose C

Copy the contents of Java’s main method into C’s main function. Expect NetBeans to light up your C program.

Let’s start removing some of those red lines. First, delete the line containing the invocation of the Random constructor and replace the calls of the gen.nextInt() method with a call to the random() function.

Now remove the System.out.’s that are in front of the printf. C isn’t a classy language. Then change System.out.println() into a simple putchar('\n'). At this point, the red lines should be gone.

However, if you try to run the program, you will see errors. C doesn’t have a >>>. Replace it with >>. Also, in the pre-C99 version of C, you are not allowed to place declarations inside the body of a for. You must declare the variable i before the for and remove the int within the for.

At this point, you have a program that should be acceptable as both C and C++. It may not be the best, but it could be another line on your resume.