RosettaCodeData/Task/Four-bit-adder/Java/four-bit-adder.java

148 lines
4.6 KiB
Java

public class GateLogic
{
// Basic gate interfaces
public interface OneInputGate
{ boolean eval(boolean input); }
public interface TwoInputGate
{ boolean eval(boolean input1, boolean input2); }
public interface MultiGate
{ boolean[] eval(boolean... inputs); }
// Create NOT
public static OneInputGate NOT = new OneInputGate() {
public boolean eval(boolean input)
{ return !input; }
};
// Create AND
public static TwoInputGate AND = new TwoInputGate() {
public boolean eval(boolean input1, boolean input2)
{ return input1 && input2; }
};
// Create OR
public static TwoInputGate OR = new TwoInputGate() {
public boolean eval(boolean input1, boolean input2)
{ return input1 || input2; }
};
// Create XOR
public static TwoInputGate XOR = new TwoInputGate() {
public boolean eval(boolean input1, boolean input2)
{
return OR.eval(
AND.eval(input1, NOT.eval(input2)),
AND.eval(NOT.eval(input1), input2)
);
}
};
// Create HALF_ADDER
public static MultiGate HALF_ADDER = new MultiGate() {
public boolean[] eval(boolean... inputs)
{
if (inputs.length != 2)
throw new IllegalArgumentException();
return new boolean[] {
XOR.eval(inputs[0], inputs[1]), // Output bit
AND.eval(inputs[0], inputs[1]) // Carry bit
};
}
};
// Create FULL_ADDER
public static MultiGate FULL_ADDER = new MultiGate() {
public boolean[] eval(boolean... inputs)
{
if (inputs.length != 3)
throw new IllegalArgumentException();
// Inputs: CarryIn, A, B
// Outputs: S, CarryOut
boolean[] haOutputs1 = HALF_ADDER.eval(inputs[0], inputs[1]);
boolean[] haOutputs2 = HALF_ADDER.eval(haOutputs1[0], inputs[2]);
return new boolean[] {
haOutputs2[0], // Output bit
OR.eval(haOutputs1[1], haOutputs2[1]) // Carry bit
};
}
};
public static MultiGate buildAdder(final int numBits)
{
return new MultiGate() {
public boolean[] eval(boolean... inputs)
{
// Inputs: A0, A1, A2..., B0, B1, B2...
if (inputs.length != (numBits << 1))
throw new IllegalArgumentException();
boolean[] outputs = new boolean[numBits + 1];
boolean[] faInputs = new boolean[3];
boolean[] faOutputs = null;
for (int i = 0; i < numBits; i++)
{
faInputs[0] = (faOutputs == null) ? false : faOutputs[1]; // CarryIn
faInputs[1] = inputs[i]; // Ai
faInputs[2] = inputs[numBits + i]; // Bi
faOutputs = FULL_ADDER.eval(faInputs);
outputs[i] = faOutputs[0]; // Si
}
if (faOutputs != null)
outputs[numBits] = faOutputs[1]; // CarryOut
return outputs;
}
};
}
public static void main(String[] args)
{
int numBits = Integer.parseInt(args[0]);
int firstNum = Integer.parseInt(args[1]);
int secondNum = Integer.parseInt(args[2]);
int maxNum = 1 << numBits;
if ((firstNum < 0) || (firstNum >= maxNum))
{
System.out.println("First number is out of range");
return;
}
if ((secondNum < 0) || (secondNum >= maxNum))
{
System.out.println("Second number is out of range");
return;
}
MultiGate multiBitAdder = buildAdder(numBits);
// Convert input numbers into array of bits
boolean[] inputs = new boolean[numBits << 1];
String firstNumDisplay = "";
String secondNumDisplay = "";
for (int i = 0; i < numBits; i++)
{
boolean firstBit = ((firstNum >>> i) & 1) == 1;
boolean secondBit = ((secondNum >>> i) & 1) == 1;
inputs[i] = firstBit;
inputs[numBits + i] = secondBit;
firstNumDisplay = (firstBit ? "1" : "0") + firstNumDisplay;
secondNumDisplay = (secondBit ? "1" : "0") + secondNumDisplay;
}
boolean[] outputs = multiBitAdder.eval(inputs);
int outputNum = 0;
String outputNumDisplay = "";
String outputCarryDisplay = null;
for (int i = numBits; i >= 0; i--)
{
outputNum = (outputNum << 1) | (outputs[i] ? 1 : 0);
if (i == numBits)
outputCarryDisplay = outputs[i] ? "1" : "0";
else
outputNumDisplay += (outputs[i] ? "1" : "0");
}
System.out.println("numBits=" + numBits);
System.out.println("A=" + firstNumDisplay + " (" + firstNum + "), B=" + secondNumDisplay + " (" + secondNum + "), S=" + outputCarryDisplay + " " + outputNumDisplay + " (" + outputNum + ")");
return;
}
}