Last Updated: 2017-10-25 Wed 09:18

CSCI 1103 Project 3: Number Conversions via Strings and Methods

CODE DISTRIBUTION: p3-code.zip

CHANGELOG:

1 Introduction

Computer scientists work with a variety of data formats though binary formats which involve only 0's and 1's are at the heart of the field. This project explores conversion between binary (base 2) and decimal (base 10) representation of positive integers. This area provides a wealth of practice

  • The algorithms involved in conversion involve arithmetic, looping, and conditionals.
  • The algorithms are easily canned into methods with well-defined inputs and outputs that are usable in several places.
  • String representations of binary numbers is a good way to get further practice with an array-like entity.
  • String methods like concatenation allow new strings of binary numbers to be represented.

All of these will combine into the three problems for this project.

If this is your first time working with binary numbers, don't be intimidated. The materials in the project specification will give you a good introduction to binary numbers. If you are seeking some additional information, the Wikipedia Article on Binary Numbers has a good introductory section and as usual, internet searches should turn up many other alternative treatments.

2 Download Code and Setup

As in Lab01, download the code pack linked at the top of the page. Unzip this which will create a folder and create your files in that folder.

File State Notes
TextIO.java Provided Allows easy input calls like TextIO.getInt()
B2DTests.java Testing Tests for Problem 1
D2BTests.java Testing Tests for Problem 2
ConversionsTests.java Testing Tests for Problem 3
KTests.java Testing Test functions, runs all project tests from command line
junit-1103.jar Testing For testing, don't try to edit this one
B2D.java Create Create this file for Problem 1
D2B.java Create Create this file for Problem 2
Conversions.java Create Create this file for Problem 3

3 Problem 1: Binary Numbers to Decimal Numbers

Everything in computing is represented with bits, 1's and 0's. This includes integers. It is an essential skill for CS folk to know how such representations work and be able to convert between binary and more standard notations. This problem explores an algorithm to convert base 2 "binary" numbers into base 10 "decimal" numbers. The goal of the problem is to write a Java method binary2Decimal() which executes this algorithm.

3.1 Number Systems

Most folks are well-acquainted with the decimal (base-10) numbering systems. This notation for numbers uses digits and placement of digits to indicate quantities. It roughly boils down to the following:

BASE 10 REPRESENTATION OF 80,345

                      | Totaling
80,345 =    5 * 10^0  | +      5 
          + 4 * 10^1  | +     40 
          + 3 * 10^2  | +    300
          + 0 * 10^3  | +      0  
          + 8 * 10^4  | + 80,000 
                        --------
                          80,435

Notice each digit of the number is multiplied by a power of 10

  • 100 = 1 is multiplied by 5
  • 102 = 100 is multiplied by 3
  • 103 = 1,000 is multiplied by a 0

As the digits go from right to left the power of 10 increases.

Also notice that there are only 9 numerals: there is no character in standard numbers that represents the number ten: instead one uses two digits 10 to show this number. The maximum value a single digit can represent is nine via 9.

For binary numbers (base-2) this notation is identical with two notable changes

  • Each digit is either a either 0 or 1; no digit with value two or larger appears.
  • Powers of 2 are used instead of powers of 10. Each digit is multiplied by a power of 2 to produce a given quantity.

An example:

BASE 2 REPRESENTATION: 25 base 10 = 11001 base 2

                          | Totaling
11001 base 2 = + 1 * 2^0  | +   1
               + 0 * 2^1  | +   0
               + 0 * 2^2  | +   0
               + 1 * 2^3  | +   8
               + 1 * 2^4  | +  16
                            -----
                               25 base 10

Each digit, either 1 or 0, is multiplied by a power 2. As the digits go from right to left the powers of 2 increase.

  • The rightmost digit represents how many 1's (0 or 1)
  • The next rightmost digit represents how many 2's (0 or 1)
  • The next rightmost digit represents how many 4's (0 or 1)
  • etc.

Totaling these together allows one to represent any number in base 2 just as any number can be written in base 10.

Here are a few more binary examples:

111 base 2 = 1 * 2^0 + 1 * 2^1 + 1 * 2^2
           = 1 * 1   + 1 * 2   + 1 * 4
           = 1 + 2 + 4
           = 7 base 10

11010 base 2 = 0*1 + 1*2 + 0*4 + 1*8 + 1*16
             = 2 + 8 + 16
             = 26 base 10

01100001 base 2 = 1*1 + 0*2 + 0*4 + 0*8 + 0*16 + 1*32 + 1*64 + 0*128
                = 1 + 32 + 64
                = 97 base 10

Note again that it is easiest to process this from right to left unlike normal English text which is read to left to right. This peculiarity is on account of modern number systems originating from parts of the world that write text from right to left.

The consequence of this right-to-left convention is that conversion methods will usually start with the right-most character and loop "backwards" to lower index digits which have higher significance in that they correspond to larger powers.

A quick note: Java 8 and DrJava both have support for binary numbers built into it. These numbers are prefixed with 0b to indicate they are binary. For example, in the DrJava interactions pane one can do the following the check conversions.

Welcome to DrJava.
> int x = 0b1101;
> x
13
> 0b111
7
> 0b11010
26
> 0b01100001
97
>

This is for purpose of checking answers only. The code you will write will require you to process binary numbers written as Strings.

3.2 Binary to Decimal Conversion Algorithm

Converting a positive a binary number into its decimal equivalent can be done using the following right approach.

Binary to Decimal Conversion Pseudocode
Input: String BINARY of 0's and 1's

set integer SUM to 0
set integer TWO_POW to 1
for I = last position in BINARY down to 0 
  if character I of BINARY is '1'
    add TWO_POW onto SUM
  set TWO_POW to be TWO_POW*2
done

SUM now contains a decimal integer of BINARY

There are several things to note about this procedure

  • The procedure is PSEUDOCODE, not Java so copying it directly won't do much good. It follows different conventions for loops and variable names but the central idea encoded is still instructive.
  • The input is a String like
    "1001011"
    
  • The length of the String is needed which can be gotten via the length() method of strings
  • Individual characters of the String need to be analyzed. These can be retrieved from the string via the charAt(index) method.

3.3 Structure of B2D.java file

Write your code in B2D.java. This file will ultimately contain two methods and be structured as follows.

public class B2D{
// Contains a method to do conversion from binary to decimal numbers
// and a main method to drive it.

  public static int binary2Decimal(String binary);
  // Return a positive int which is the decimal value of the binary
  // number passed in as a parameter. If any character in the binary
  // number is invalid (not '0' or '1') return -1. DO NOT print
  // anything during this method.

  public static void main(String args[]);
  // Prompt the user for a binary number. Read it as a string and use
  // the method binary2Decimal() to convert to an int.  Print the
  // results as a decimal number. If the conersion fails, loop through
  // the binary number and print out all invalid characters in it
  // (characters which are not '0' and not '1').

}

3.4 binary2Decimal() method

  • Encode the algorithm described above in the binary to decimal section as a Java method with the following signature:
    public static int binary2Decimal(String binary)
    
  • The method takes a parameter string and returns an integer
  • The integer returned should be the decimal value of the binary number encoded in the parameter string
  • If any character in binary is not a 0 or 1, the binary number is invalid. In this case, the method should return -1 as its answer.

Ensure that you adhere to the following restrictions while writing the binary2Decimal() method.

  • This method SHOULD NOT use TextIO nor should it print anything. Instead all information it needs is passed in the parameter binary and the answer it computes is returned in a return ans; statement.
  • Since the method signature indicates an int should be returned, there must be a return ans; statement in the method.

3.5 Interactive Testing of binary2Decimal() and Demos

Since this binary2Decimal() is a NOT a main() method, testing it is a bit tricky. One approach is to write a main() method which allows it to be used. This is the next step for the problem.

Another approach to testing non- main() methods is enabled in DrJava's Interactions Pane. In it, one can directly make calls to any static method. Here are some demos.

Welcome to DrJava.
> int ten = B2D.binary2Decimal("1010");
> ten
10
> String bin = "100001101";
> System.out.println( B2D.binary2Decimal(bin) )
269
> B2D.binary2Decimal("11111010")
250
> B2D.binary2Decimal("hello")
-1
> B2D.binary2Decimal("1001a01")
-1

Notice that the syntax in the Interactions Pane is accommodating: one need only invoke a method like

> B2D.binary2Decimal("11111010")

and the return value will be printed on the next line by default.

Interactive testing good to do while working on your methods as it will allow you to see problems early on and begin forming input/output associations.

3.6 main() Method for B2D : Driving the conversion method

Typically methods like binary2Decimal() are written so that they can be used in a variety of places. The first place it will be used is in the main() method of the class B2D. This main method should not execute the algorithm for binary to decimal conversion itself but rather invoke the binary2Decimal() method to do this. The basic approach of main() is as follows.

  • Prompt the user for a binary number
  • Use TextIO.getWord() to read the word from the user
  • Call binary2Decimal() to convert the binary number to a decimal integer
  • If the conversion succeeds, print the decimal number on the screen
  • If the conversion fails, print an error message
    Failed to convert
    

    and then loop through the characters of the binary number and print all invalid characters in a message as in

    invalid character 'x'
    invalid character 'a'
    

Here is a demo of compiling and running the B2D main method from the command line. This process works nearly identically via the Run option of DrJava..

> javac B2D.java
> java B2D
Enter a binary number: (ex: 011010101)
110110
Decimal value: 54
> java B2D
Enter a binary number: (ex: 011010101)
0000101
Decimal value: 5
> java B2D
Enter a binary number: (ex: 011010101)
11
Decimal value: 3
> java B2D
Enter a binary number: (ex: 011010101)
abcd
Failed to convert
invalid character 'a'
invalid character 'b'
invalid character 'c'
invalid character 'd'
> java B2D
Enter a binary number: (ex: 011010101)
1010h001
Failed to convert
invalid character 'h'
>

Sometimes the main() method is referred to as a driver for methods: drivers get input, call methods which do most of the real work, and display output (this may be a reference to a car driver pushing peddles while the car actually does the work of going from place to another at high speed).

Note that there are test cases specifically for the binary2Decimal() method and also separate tests for the main() method. Both of these must be present work in order to receive full credit.

3.7 Problem 1 Binary to Decimal Manual Inspection Criteria   grading

The criteria below will be examined by graders to account for part of your grade.

Wgt Criteria
5% Good style, indentation, and variable name choices are used
3% binary2Decimal() method does not print and does not use TextIO
2% main() calls binary2Decimal() to convert the string entered to a decimal integer
5% binary2Decimal() uses the algorithm described to accomplish conversion and calls appropriate string methods like charAt() and length()
15% Total weight for these criteria

4 Problem 2: Decimal to Binary Conversion

As one can convert numbers written in binary to decimal, the decimal to binary conversion is also possible. This problem explores an algorithm to just that and results in a similar set of code to provide a decimal2Binary() method and a main() method to allow its interactive use.

4.1 An algorithm for decimal to binary conversion

The foremost step in going from base 10 to base 2 is to recognize that a binary number shows how many 1's, 2's, 4's, 8's, 16's, and so forth should be added together to get a value. With a decimal number in hand, this process involves repeated division and modulo. Consider the following example which demonstrates the conversion of 124 to binary.

CONVERT 124 base 10 to base 2
Repeatedly divid by 2 and track remainders
       Quotient         Remainder
124 / 2 = 62     124 % 2 = 0 last digit
 62 / 2 = 31      62 % 2 = 0 
 31 / 2 = 15      31 % 2 = 1 
 15 / 2 =  7      15 % 2 = 1 middle digit
  7 / 2 =  3       7 % 2 = 1 
  3 / 2 =  1       3 % 2 = 1 
  1 / 2 =  0       1 % 2 = 1 first digit
Quotient = 0; terminate

ANSWER is remainders in reverse order:
1111100 base 2 = 124 base 10

CHECK: 
1111100 base 2 = 0+0+2^2+2^3+2^4+2^5+2^6 
               = 4+8+16+32+64 
               = 124 base 10
  • Notice that each step divides a number by 2 to get a quotient and uses the modulo % operator to find the remainder as well
  • In the next step, the quotient from the previous step is again divided to produce a new quotient and remainder
  • The digits for the binary number come from the sequence of remainders which are always 0 or 1
  • The sequence of remainders in reverse order comprises the binary number answer

A second example is in order.

CONVERT 19 base 10 to base 2
Repeatedly divid by 2 and track remainders
       Quotient         Remainder
19 / 2 = 9     19 % 2 = 1 last digit
 9 / 2 = 4      9 % 2 = 1 
 4 / 2 = 2      4 % 2 = 0 middle digit
 2 / 2 = 1      2 % 2 = 0 
 1 / 2 = 0      1 % 2 = 1 first digit
Quotient = 0; terminate

ANSWER is remainders in reverse order:
10011 base 2 = 19 base 10

CHECK: 
10011 base 2 = 2^0+2^1+0+0+2^4
             = 1+2+16
             = 19 base 10

4.2 Decimal To Binary Conversion Algorithm

Below is pseudo-code describing the general process of converting a decimal number to a binary number.

Decimal to Binary Conversion Pseudocode
Input X, a decimal number

set ANSWER to be "" (empty string)
repeat until X is 0:
    set QUOTIENT to X divided by 2
    set REMAIDER to X modulo 2
    Prepend REMAINDER to the LEFT side of ANSWER
    Set X to be QUOTIENT
done

if ANSWER is ""
  set ANSWER to "0"
end

ANSWER now contains the binary representation for X
  • This process uses a loop for which the bounds are not known ahead of time
  • Both division and modulo are used
  • The answer is a String. During processing, this string has characters "added" to the beginning of it. The Java equivalent of this is string concatenation, typically using the + operator on strings.
  • One special case is handled: if the input number X is 0, the binary conversion will return the string 0

4.3 Structure of D2B.java file

Write your code in D2B.java. This file will ultimately contain two methods and be structured as follows.

public class D2B{
// Class which contains a method for doing decimal to binary
// conversions along with a main method to drive it.

  public static String decimal2Binary(int decimal);
  // Return a String which is the binary representation of the
  // parameter decimal integer. If the decimal number is less than 0,
  // return null. DO NOT print anything during this method.

  public static void main(String args[]);
  // Prompt the user to enter a decimal number. After reading it, use
  // decimal2Binary() to convert to a String representing the binary
  // coding of the number.  Print this to the screen. If the
  // conversion fails, print the line
  // 
  // "Can't convert decimals less than 0"

}

4.4 decimal2Binary() method

  • Encode the algorithm described above in the decimal to binary section as a Java method with the following signature:
    public static String decimal2Binary(int decimal)
    
    • The method takes a parameter integer and returns a string
    • The string returned should be the binary representation of the argument decimal
    • The algorithm will specified will not work for negative integers. The method should check if decimal is negative and return null immediately before entering the computation loop.

Ensure that you adhere to the following restrictions while writing the binary2Decimal() method.

  • This method SHOULD NOT use TextIO nor should it print anything. Instead all information it needs is passed in the parameter decimal and the answer it computes is returned in a return ans; statement.
  • Since the method signature indicates an String should be returned, there must be a return ans; statement in the method.

4.5 Interactive Testing of decimal2Binary() and Demos

As before, one can interactively test the decimal2Binary() method in the DrJava interactions pane such as the following.

Welcome to DrJava.
> int x = 19;
> String ans = D2B.decimal2Binary(x);
> System.out.println(ans)
10011
> D2B.decimal2Binary(124)
1111100
> D2B.decimal2Binary(22)
10110
> D2B.decimal2Binary(512)
1000000000
> D2B.decimal2Binary(1023)
1111111111
> D2B.decimal2Binary(999)
1111100111

4.6 main() Method for D2B

As with B2D, write a main() method for D2B which allows for testing of the decimal2Binary() method. The basic approach of this method is as follows.

  • Prompt the user for an integer and read it using TextIO
  • Call the binary2Decimal() method to carry out a conversion of the number to binary
  • If the conversion succeeds, print the result
  • If the conversion fails, print the message
    Can't convert decimals less than 0
    

Below are demos of compiling and running the D2B main method on the command line.

> javac D2B.java
> java D2B
Enter a decimal number: (ex: 546723)
124
Binary value: 1111100
> java D2B
Enter a decimal number: (ex: 546723)
19
Binary value: 10011
> java D2B
Enter a decimal number: (ex: 546723)
1025
Binary value: 10000000001
> java D2B
Enter a decimal number: (ex: 546723)
-16
Can't convert decimals less than 0
> java D2B
Enter a decimal number: (ex: 546723)
0
Binary value: 0

4.7 Problem 2 Decimal to Binary Manual Inspection Criteria   grading

The criteria below will be examined by graders to account for part of your grade.

Wgt Criteria
5% Good style, indentation, and variable name choices are used
3% decimal2Binary() method does not print and does not use TextIO
2% main() calls decimal2Binary() to convert the decimal integer entered to a binary string
5% decimal2Binary() uses the algorithm described to accomplish conversion using string concatenation to build the answer string up
15% Total weight for these criteria

5 Problem 3: Converting Either Way

Once written, methods can be called from any other code location by specifying their full name. In our case, the two conversion methods could be called from other files/classes/programs via:

int decimal = B2D.binary2Decimal(string);

String binary = D2B.decimal2Binary(number);

where the name of the class containing the method appears first, followed by a dot and then the method name.

In this problem, we will make use of this facility to write a converter which handles either to decimal to binary or binary to decimal conversions. The code will NOT need to re-implement the conversion algorithms as one can simply call the binary2Decimal() and decimal2Binary() method defined in the previous classes.

5.1 Basic Approach

  • Write your code in the file Conversions.java
  • Initially prompt the user for the words binary or decimal which indicates whether the input will be a decimal or binary number
  • If the user enters binary
    • Prompt for a binary number and read it
    • Call the binary2Decimal() method to convert it to a decimal number
    • If the conversion fails print
      Failed to convert
      

      and take no further action. return might be useful for this.

    • If the conversion succeeds, print the decimal number in a message like
      Decimal value: 77
      
    • Convert the decimal number back to binary using decimal2Binary() and print the result in a message like
      Back to binary: 1001101
      
  • If the user enters decimal
    • Prompt for a decimal number and read it
    • Call the decimal2Binary() method to convert it to a binary number
    • If the conversion fails print
      Failed to convert
      

      and take no further action. return might be useful for this.

    • If the conversion succeeds, print the binary number in a message like
      Binary value: 1111100
      
    • Convert the binary number back to decimal using binary2Decimal() and print the result in a message like
      Back to decimal: 124
      
  • If the choice entered is neither binary or decimal, print a message indicating the unknown choice:
    Unknown choice 'morty'
    

5.2 Demos

> javac Conversions.java

# Successful binary conversion
> java Conversions
Choose 'binary' or 'decimal' number:
binary
Enter a binary number: (ex: 011010101)
1001101
Decimal value: 77
Back to binary: 1001101

# Successful decimal conversion
> java Conversions
Choose 'binary' or 'decimal' number:
decimal
Enter a decimal number: (ex: 546723)
124
Binary value: 1111100
Back to decimal: 124

# Bad input choice
> java Conversions
Choose 'binary' or 'decimal' number:
morty
Unknown choice 'morty'

# Error for binary number
> java Conversions
Choose 'binary' or 'decimal' number:
binary
Enter a binary number: (ex: 011010101)
1011abc10
Failed to convert

# Error for decimal number
> java Conversions
Choose 'binary' or 'decimal' number:
decimal
Enter a decimal number: (ex: 546723)
-15
Failed to convert
>

5.3 Problem 3 Conversions Manual Inspection Criteria   grading

The criteria below will be examined by graders to account for part of your grade.

Wgt Criteria
5% Good style, indentation, and variable name choices are used
5% binary2Decimal() and decimal2Binary() method are NOT redefined; they are used directly from the B2D and D2B classes.
5% The main() method follows a clear conditional structure which checks the first input and takes appropriate actions
2% The equals() method is used to compare strings correctly for the first input
3% The results of binary2Decimal() and decimal2Binary() are checked for success and error messages are printed if conversion fails
20% Total weight for these criteria

6 Automatic Testing (50%)   grading

6.1 Running Tests

Run the tests associated with the project and ensure all of them pass. This can be done in DrJava by pressing the Test button when test files are open.

On the command line you can run all tests with the following commands.

On Unix/Mac platforms, use a terminal to run the following commands in the folder where your code exists.

> javac -cp .:junit-1103.jar KTests.java   #compile
> java -cp .:junit-1103.jar KTests         #run tests

On windows, use cmd.exe and change to the correct directory. Run the commands below where which use a semicolon (;) rather than a colon (:).

> javac -cp .;junit-1103.jar KTests.java   #compile
> java -cp .;junit-1103.jar KTests         #run tests

Correctly passing all tests will yield output similar to the following.

JUnit version 4.12
..........
Time: 0.024

OK (10 tests)

Failing some tests will yield long messages which hint at where there might be a problem. Failures always end with the number of tests passed/failed as in the following.

FAILURES!!!
Tests run: 10,  Failures: 5

6.2 Test Grading Policies

Some policies to keep in mind with respect to how automatic tests affect grades.

  • Credit on this section is proportional to the number of tests passed.
  • If there were 30 total tests for the project…
  • Passing 30 / 30 tests gets 30 / 30 * 50 = 50.00
  • Passing 15 / 30 tests gets 15 / 30 * 50 = 25.00
  • Passing 4 / 30 tests gets 4 / 30 * 50 = 6.67
  • A 5% penalty may be deducted from this portion if code does not compile initially but a grader is able to quickly fix the problem.
  • Passing no tests because code does not compile or does not work properly gets 0 credit.

7 Zip and Submit

7.1 Submit to Canvas

Once your are confident your code is working, you are ready to submit. Ensure your folder has all of the required files. Create a zip archive of your lab folder and submit it to blackboard.

On Canvas:

  • Click on the Assignments section
  • Click on the appropriate link for this lab
  • Scroll down to "Attach a File"
  • Click "Browse My Computer"
  • Select you Zip file and press OK

7.2 Late Policies

You may wish to review the policy on late project submission which will cost you late tokens to submit late or credit if you run out of tokens. No projects will be accepted more than 48 hours after the deadline.

http://www-users.cs.umn.edu/~kauffman/1103/syllabus.html#late-projects


Author: Chris Kauffman (kauffman@umn.edu)
Date: 2017-10-25 Wed 09:18