In: Electrical Engineering
Write a parity checker for the ASCII system in MARIE. MARIE is an assembly language. The parity checker should repeatedly execute a loop that performs the following tasks: 1. Ask the user for an input X, which can be any printable ASCII character from Table 1; 2. Output the decimal code of X; 3. Output the total number of 1’s that appears in the binary code of X; 4. Output the parity bit which, when added to the binary code of X, will make the number of 1’s even.
import MarieSimTester.Test; |
static class Parity { |
static final byte start = 33; // Start at 33 instead of 32 (because 32 is whitespace, which is not directly accepted by MarieSim) |
static final byte end = 126; // End at the last ASCII code. |
// default sample program for this project |
static final String DefaultMasfilepath = "testbed/parity-brute.mas"; |
// Generate the sequence of ascii characters within the given range and including the boundary. |
public String input(int start, int end) { |
// If the range is invalid, fix it with the correct range. |
if (start<Parity.start) start=Parity.start; |
if (end>Parity.end) end=Parity.end; |
String ascii = ""; |
for (byte i=(byte)start; i<=(byte)end; i++) { |
// Convert the byte to character (note: Java uses unicode) |
char c = (char) i; |
if (ascii.length()!=0) |
ascii += " "; |
ascii += c; |
} |
return ascii; |
} |
public String toBinary(char c) { |
// Convert the byte to binary string |
// Reference: http://stackoverflow.com/questions/12310017/how-to-convert-a-byte-to-its-binary-string-representation |
return String.format("%8s", Integer.toBinaryString(c & 0xFF)).replace(' ', '0'); |
} |
// Provide result for each ascii character |
// Output for each character includes: |
// (1) the decimal value of the ASCII code |
// (2) the number bits with value 1 in the code |
// (3) whether an additional 1 bit is needed to make the parity even. |
public String output(char c) { |
// Convert the char to decimal |
String binary = toBinary(c); |
int dec = (int) (c & 0xFF); |
// Count the number of 1s in the binary string. |
// Reference: http://stackoverflow.com/questions/275944/java-how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string |
int count = binary.length() - binary.replace("1", "").length(); |
int parity = count%2==0 ? 0 : 1; |
return dec + " " + count + " " + parity; |
} |
public String output(String input) { |
if (input==null) return null; |
// split input by whitespaces. |
String[] chars = input.trim().split("\\s"); |
String result = ""; |
for (String token : chars) { |
if (token.length()>=1) { |
if (result.length()>0) result += " "; |
result += output(token.charAt(0)); |
} |
} |
return result; |
} |
// Provide result for each ascii character in the specific range. |
public String output(int start, int end) { |
if (start<Parity.start) start=Parity.start; |
if (end>Parity.end) end=Parity.end; |
String result = ""; |
for (byte i=(byte)start; i<=(byte)end; i++) { |
result += output((char) i) + " "; |
} |
return result; |
} |
// Support printing of ascii for visual verification if needed. |
public void print() { |
for (byte i=start; i<=end; i++) { |
char c = (char) i; |
// Add a space every 4 bits for ease of reading. |
String binary = toBinary(c); |
binary = binary.substring(1, 4) + " " + binary.substring(4, 8); |
System.out.println(c + " " + binary + " " + output(c)); |
} |
} |
} |
public static void testSingleRun(String masfilepath) { |
Parity fn = new Parity(); |
// Test just the first few ASCII characters. |
int start=33; |
int end=35; |
final String input = fn.input(start, end); |
final String expectedOutput = fn.output(start, end); |
final int maxPollCount = 10; |
if (masfilepath==null) masfilepath = fn.DefaultMasfilepath; |
(new Test()).singleRunAscii2Dec(masfilepath, input, expectedOutput, maxPollCount); |
} |
public static void testMultiRunAllChars(String masfilepath) { |
Parity fn = new Parity(); |
final int inputsPerRun = 10; |
final int maxPollCount = (int)((double)inputsPerRun*2.5); // tune accordingly to allow enough time. |
// Test all ASCII characters |
int total = (int)(Parity.end-Parity.start)+1; |
// Count the total number of runs. |
int runs = (int) Math.ceil((double)total/(double)inputsPerRun); |
String inputs[] = new String[runs]; |
String expectedOutputs[] = new String[runs]; |
for (int run=0; run<runs; run++) { |
int start = run*inputsPerRun + Parity.start; |
int end = start + inputsPerRun - 1; |
// If start or end is out of range, the fn method will automatically fix it. |
inputs[run] = fn.input(start, end); |
expectedOutputs[run] = fn.output(start, end); |
} |
if (masfilepath==null) masfilepath = fn.DefaultMasfilepath; |
(new Test()).multiRunsAscii2Dec(masfilepath, inputs, expectedOutputs, maxPollCount); |
} |
public static void testMultiRun(String masfilepath) { |
Parity fn = new Parity(); |
final int inputsPerRun = 6; |
final int maxPollCount = (int)((double)inputsPerRun*2.5); // tune accordingly to allow enough time. |
String inputs[] = { "H i !", |
"{ W }", |
"z Z", |
"2 3 4", |
"A b C d", |
"@ A d e g o"}; |
String expectedOutputs[] = new String[inputs.length]; |
for (int run=0; run<inputs.length; run++) { |
expectedOutputs[run] = fn.output(inputs[run]); |
} |
if (masfilepath==null) masfilepath = fn.DefaultMasfilepath; |
(new Test()).multiRunsAscii2Dec(masfilepath, inputs, expectedOutputs, maxPollCount); |
} |
public static void main(String args[]) { |
if (args.length>=1) { |
testMultiRunAllChars(args[0]); |
} |
else { |
// default |
Usage.print(TestParity.class, Parity.DefaultMasfilepath); |
testMultiRunAllChars(null); |
} |
} |
}