0da1c5dcca
First commit of the 4.5 version (latest version available)
949 lines
49 KiB
Java
949 lines
49 KiB
Java
package mars.tools;
|
|
import mars.*;
|
|
import mars.util.*;
|
|
import mars.assembler.*;
|
|
import mars.mips.instructions.*;
|
|
import mars.mips.hardware.*;
|
|
import java.util.*;
|
|
import java.io.*;
|
|
import java.awt.*;
|
|
import java.awt.event.*;
|
|
import javax.swing.*;
|
|
import javax.swing.event.*;
|
|
import javax.swing.border.*;
|
|
import javax.swing.text.html.*;
|
|
|
|
/*
|
|
Copyright (c) 2003-2006, Pete Sanderson and Kenneth Vollmar
|
|
|
|
Developed by Pete Sanderson (psanderson@otterbein.edu)
|
|
and Kenneth Vollmar (kenvollmar@missouristate.edu)
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
a copy of this software and associated documentation files (the
|
|
"Software"), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
permit persons to whom the Software is furnished to do so, subject
|
|
to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
(MIT license, http://www.opensource.org/licenses/mit-license.html)
|
|
*/
|
|
|
|
/**
|
|
* Tool to help students learn about IEEE 754 representation of 32 bit
|
|
* floating point values. This representation is used by MIPS "float"
|
|
* directive and instructions and also the Java (and most other languages)
|
|
* "float" data type. As written, it can ALMOST be adapted to 64 bit by
|
|
* changing a few constants.
|
|
*/
|
|
public class FloatRepresentation extends AbstractMarsToolAndApplication {
|
|
private static String version = "Version 1.1";
|
|
private static String heading = "32-bit IEEE 754 Floating Point Representation";
|
|
private static final String title = "Floating Point Representation, ";
|
|
|
|
private static final String defaultHex = "00000000";
|
|
private static final String defaultDecimal = "0.0";
|
|
private static final String defaultBinarySign = "0";
|
|
private static final String defaultBinaryExponent = "00000000";
|
|
private static final String defaultBinaryFraction = "00000000000000000000000";
|
|
private static final int maxLengthHex = 8;
|
|
private static final int maxLengthBinarySign = 1;
|
|
private static final int maxLengthBinaryExponent = 8;
|
|
private static final int maxLengthBinaryFraction = 23;
|
|
private static final int maxLengthBinaryTotal = maxLengthBinarySign+maxLengthBinaryExponent+maxLengthBinaryFraction;
|
|
private static final int maxLengthDecimal = 20;
|
|
private static final String denormalizedLabel = " significand (denormalized - no 'hidden bit')";
|
|
private static final String normalizedLabel = " significand ('hidden bit' underlined) ";
|
|
private static final Font instructionsFont = new Font("Arial",Font.PLAIN,14);
|
|
private static final Font hexDisplayFont = new Font("Courier",Font.PLAIN,32);
|
|
private static final Font binaryDisplayFont = new Font("Courier",Font.PLAIN,18);
|
|
private static final Font decimalDisplayFont = new Font("Courier",Font.PLAIN,18);
|
|
private static final Color hexDisplayColor = Color.red;
|
|
private static final Color binaryDisplayColor = Color.black;
|
|
private static final Color decimalDisplayColor = Color.blue;
|
|
private static final String expansionFontTag = "<font size=\"+1\" face=\"Courier\" color=\"#000000\">";
|
|
private static final String instructionFontTag = "<font size=\"+0\" face=\"Verdana, Arial, Helvetica\" color=\"#000000\">";
|
|
private static final int exponentBias = 127; // 32 bit floating point exponent bias
|
|
|
|
private Register attachedRegister = null;
|
|
private Register[] fpRegisters;
|
|
private FloatRepresentation thisFloatTool;
|
|
// Panels to hold binary displays and decorations (labels, arrows)
|
|
private JPanel binarySignDecoratedDisplay,
|
|
binaryExponentDecoratedDisplay, binaryFractionDecoratedDisplay;
|
|
// Editable fields for the hex, binary and decimal representations.
|
|
private JTextField hexDisplay, decimalDisplay,
|
|
binarySignDisplay, binaryExponentDisplay, binaryFractionDisplay;
|
|
// Non-editable fields to display formula translating binary to decimal.
|
|
private JLabel expansionDisplay;
|
|
private JLabel significandLabel = new JLabel(denormalizedLabel, JLabel.CENTER);
|
|
private BinaryToDecimalFormulaGraphic binaryToDecimalFormulaGraphic;
|
|
// Non-editable field to display instructions
|
|
private InstructionsPane instructions;
|
|
private String defaultInstructions = "Modify any value then press the Enter key to update all values.";
|
|
|
|
/**
|
|
* Simple constructor, likely used to run a stand-alone memory reference visualizer.
|
|
* @param title String containing title for title bar
|
|
* @param heading String containing text for heading shown in upper part of window.
|
|
*/
|
|
public FloatRepresentation(String title, String heading) {
|
|
super(title,heading);
|
|
thisFloatTool = this;
|
|
}
|
|
|
|
/**
|
|
* Simple constructor, likely used by the MARS Tools menu mechanism
|
|
*/
|
|
public FloatRepresentation() {
|
|
this(title+version, heading);
|
|
}
|
|
|
|
/**
|
|
* Main provided for pure stand-alone use. Recommended stand-alone use is to write a
|
|
* driver program that instantiates a FloatRepresentation object then invokes its go() method.
|
|
* "stand-alone" means it is not invoked from the MARS Tools menu. "Pure" means there
|
|
* is no driver program to invoke the application.
|
|
*/
|
|
public static void main(String[] args) {
|
|
new FloatRepresentation(title+version,heading).go();
|
|
}
|
|
|
|
/**
|
|
* Fetch tool name (for display in MARS Tools menu)
|
|
* @return String containing tool name
|
|
*/
|
|
public String getName() {
|
|
return "Floating Point Representation";
|
|
}
|
|
|
|
/**
|
|
* Override the inherited method, which registers us as an Observer over the static data segment
|
|
* (starting address 0x10010000) only. This version will register us as observer over the selected
|
|
* floating point register, if any. If no register is selected, it will not do anything.
|
|
* If you use the inherited GUI buttons, this method is invoked when you click "Connect" button
|
|
* on MarsTool or the "Assemble and Run" button on a Mars-based app.
|
|
*/
|
|
protected void addAsObserver() {
|
|
addAsObserver(attachedRegister);
|
|
}
|
|
|
|
/**
|
|
* Delete this app/tool as an Observer of the attached register. This overrides
|
|
* the inherited version which deletes only as an Observer of memory.
|
|
* This method is called when the default "Disconnect" button on a MarsTool is selected or
|
|
* when the MIPS program execution triggered by the default "Assemble and run" on a stand-alone
|
|
* Mars app terminates (e.g. when the button is re-enabled).
|
|
*/
|
|
protected void deleteAsObserver() {
|
|
deleteAsObserver(attachedRegister);
|
|
}
|
|
|
|
/**
|
|
* Method that constructs the main display area. This will be vertically sandwiched between
|
|
* the standard heading area at the top and the control area at the bottom.
|
|
* @return the GUI component containing the application/tool-specific part of the user interface
|
|
*/
|
|
protected JComponent buildMainDisplayArea() {
|
|
return buildDisplayArea();
|
|
}
|
|
|
|
/**
|
|
* Override inherited update() to update display when "attached" register is modified
|
|
* either by MIPS program or by user editing it on the MARS user interface.
|
|
* The latter is the reason for overriding the inherited update() method.
|
|
* The inherited method will filter out notices triggered by the MARS GUI or the user.
|
|
* @param register the attached register
|
|
* @param accessNotice information provided by register in RegisterAccessNotice object
|
|
*/
|
|
public void update(Observable register, Object accessNotice) {
|
|
if (((AccessNotice)accessNotice).getAccessType()==AccessNotice.WRITE) {
|
|
updateDisplays(new FlavorsOfFloat().buildOneFromInt(attachedRegister.getValue()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method to reset display values to 0 when the Reset button selected.
|
|
* If attached to a MIPS register at the time, the register will be reset as well.
|
|
* Overrides inherited method that does nothing.
|
|
*/
|
|
protected void reset() {
|
|
instructions.setText(defaultInstructions);
|
|
updateDisplaysAndRegister(new FlavorsOfFloat());
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
// Private methods defined to support the above.
|
|
|
|
protected JComponent buildDisplayArea() {
|
|
// Panel to hold all floating point dislay and editing components
|
|
Box mainPanel = Box.createVerticalBox();
|
|
JPanel leftPanel = new JPanel(new GridLayout(5,1,0,0));
|
|
JPanel rightPanel = new JPanel(new GridLayout(5,1,0,0));
|
|
Box subMainPanel = Box.createHorizontalBox();
|
|
subMainPanel.add(leftPanel);
|
|
subMainPanel.add(rightPanel);
|
|
mainPanel.add(subMainPanel);
|
|
|
|
// Editable display for hexadecimal version of the float value
|
|
hexDisplay = new JTextField(defaultHex, maxLengthHex+1);
|
|
hexDisplay.setFont(hexDisplayFont);
|
|
hexDisplay.setForeground(hexDisplayColor);
|
|
hexDisplay.setHorizontalAlignment(JTextField.RIGHT);
|
|
hexDisplay.setToolTipText(""+maxLengthHex+"-digit hexadecimal (base 16) display");
|
|
hexDisplay.setEditable(true);
|
|
hexDisplay.revalidate();
|
|
hexDisplay.addKeyListener(new HexDisplayKeystrokeListener(8));
|
|
|
|
JPanel hexPanel = new JPanel();
|
|
hexPanel.add(hexDisplay);
|
|
//################ Grid Row : Hexadecimal ##################################
|
|
leftPanel.add(hexPanel);
|
|
|
|
HexToBinaryGraphicPanel hexToBinaryGraphic = new HexToBinaryGraphicPanel();
|
|
//################ Grid Row : Hex-to-binary graphic ########################
|
|
leftPanel.add(hexToBinaryGraphic);
|
|
|
|
// Editable display for binary version of float value.
|
|
// It is split into 3 separately editable components (sign,exponent,fraction)
|
|
|
|
binarySignDisplay = new JTextField(defaultBinarySign, maxLengthBinarySign+1);
|
|
binarySignDisplay.setFont(binaryDisplayFont);
|
|
binarySignDisplay.setForeground(binaryDisplayColor);
|
|
binarySignDisplay.setHorizontalAlignment(JTextField.RIGHT);
|
|
binarySignDisplay.setToolTipText("The sign bit");
|
|
binarySignDisplay.setEditable(true);
|
|
binarySignDisplay.revalidate();
|
|
|
|
binaryExponentDisplay = new JTextField(defaultBinaryExponent, maxLengthBinaryExponent+1);
|
|
binaryExponentDisplay.setFont(binaryDisplayFont);
|
|
binaryExponentDisplay.setForeground(binaryDisplayColor);
|
|
binaryExponentDisplay.setHorizontalAlignment(JTextField.RIGHT);
|
|
binaryExponentDisplay.setToolTipText(""+maxLengthBinaryExponent+"-bit exponent");
|
|
binaryExponentDisplay.setEditable(true);
|
|
binaryExponentDisplay.revalidate();
|
|
|
|
binaryFractionDisplay = new BinaryFractionDisplayTextField(defaultBinaryFraction, maxLengthBinaryFraction+1);
|
|
binaryFractionDisplay.setFont(binaryDisplayFont);
|
|
binaryFractionDisplay.setForeground(binaryDisplayColor);
|
|
binaryFractionDisplay.setHorizontalAlignment(JTextField.RIGHT);
|
|
binaryFractionDisplay.setToolTipText(""+maxLengthBinaryFraction+"-bit fraction");
|
|
binaryFractionDisplay.setEditable(true);
|
|
binaryFractionDisplay.revalidate();
|
|
|
|
binarySignDisplay.addKeyListener(new BinaryDisplayKeystrokeListener(maxLengthBinarySign));
|
|
binaryExponentDisplay.addKeyListener(new BinaryDisplayKeystrokeListener(maxLengthBinaryExponent));
|
|
binaryFractionDisplay.addKeyListener(new BinaryDisplayKeystrokeListener(maxLengthBinaryFraction));
|
|
JPanel binaryPanel = new JPanel();
|
|
|
|
binarySignDecoratedDisplay = new JPanel(new BorderLayout());
|
|
binaryExponentDecoratedDisplay = new JPanel(new BorderLayout());
|
|
binaryFractionDecoratedDisplay = new JPanel(new BorderLayout());
|
|
binarySignDecoratedDisplay.add(binarySignDisplay,BorderLayout.CENTER);
|
|
binarySignDecoratedDisplay.add(new JLabel("sign",JLabel.CENTER),BorderLayout.SOUTH);
|
|
binaryExponentDecoratedDisplay.add(binaryExponentDisplay,BorderLayout.CENTER);
|
|
binaryExponentDecoratedDisplay.add(new JLabel("exponent",JLabel.CENTER),BorderLayout.SOUTH);
|
|
binaryFractionDecoratedDisplay.add(binaryFractionDisplay,BorderLayout.CENTER);
|
|
binaryFractionDecoratedDisplay.add(new JLabel("fraction",JLabel.CENTER),BorderLayout.SOUTH);
|
|
|
|
binaryPanel.add(binarySignDecoratedDisplay);
|
|
binaryPanel.add(binaryExponentDecoratedDisplay);
|
|
binaryPanel.add(binaryFractionDecoratedDisplay);
|
|
|
|
//################ Grid Row : Binary ##################################
|
|
leftPanel.add(binaryPanel);
|
|
|
|
//################ Grid Row : Binary to decimal formula arrows ##########
|
|
binaryToDecimalFormulaGraphic = new BinaryToDecimalFormulaGraphic();
|
|
binaryToDecimalFormulaGraphic.setBackground(leftPanel.getBackground());
|
|
leftPanel.add(binaryToDecimalFormulaGraphic);
|
|
|
|
// Non-Editable display for expansion of binary representation
|
|
|
|
expansionDisplay = new JLabel(new FlavorsOfFloat().expansionString);
|
|
expansionDisplay.setFont(new Font("Monospaced",Font.PLAIN,12));
|
|
expansionDisplay.setFocusable(false); // causes it to be skipped in "tab sequence".
|
|
expansionDisplay.setBackground(leftPanel.getBackground());
|
|
JPanel expansionDisplayBox = new JPanel(new GridLayout(2,1));
|
|
expansionDisplayBox.add(expansionDisplay);
|
|
expansionDisplayBox.add(significandLabel); // initialized at top
|
|
//################ Grid Row : Formula mapping binary to decimal ########
|
|
leftPanel.add(expansionDisplayBox);
|
|
|
|
// Editable display for decimal version of float value.
|
|
decimalDisplay = new JTextField(defaultDecimal, maxLengthDecimal+1);
|
|
decimalDisplay.setFont(decimalDisplayFont);
|
|
decimalDisplay.setForeground(decimalDisplayColor);
|
|
decimalDisplay.setHorizontalAlignment(JTextField.RIGHT);
|
|
decimalDisplay.setToolTipText("Decimal floating point value");
|
|
decimalDisplay.setMargin(new Insets(0,0,0,0));
|
|
decimalDisplay.setEditable(true);
|
|
decimalDisplay.revalidate();
|
|
decimalDisplay.addKeyListener(new DecimalDisplayKeystokeListenter());
|
|
Box decimalDisplayBox = Box.createVerticalBox();
|
|
decimalDisplayBox.add(Box.createVerticalStrut(5));
|
|
decimalDisplayBox.add(decimalDisplay);
|
|
decimalDisplayBox.add(Box.createVerticalStrut(15));
|
|
|
|
FlowLayout rightPanelLayout = new FlowLayout(FlowLayout.LEFT);
|
|
JPanel place1 = new JPanel(rightPanelLayout);
|
|
JPanel place2 = new JPanel(rightPanelLayout);
|
|
JPanel place3 = new JPanel(rightPanelLayout);
|
|
JPanel place4 = new JPanel(rightPanelLayout);
|
|
|
|
JEditorPane hexExplain = new JEditorPane("text/html",expansionFontTag+"< Hexadecimal representation"+"</font>");
|
|
hexExplain.setEditable(false);
|
|
hexExplain.setFocusable(false);
|
|
hexExplain.setForeground(Color.black);
|
|
hexExplain.setBackground(place1.getBackground());
|
|
JEditorPane hexToBinExplain = new JEditorPane("text/html",expansionFontTag+"< Each hex digit represents 4 bits"+"</font>");
|
|
hexToBinExplain.setEditable(false);
|
|
hexToBinExplain.setFocusable(false);
|
|
hexToBinExplain.setBackground(place2.getBackground());
|
|
JEditorPane binExplain = new JEditorPane("text/html",expansionFontTag+"< Binary representation"+"</font>");
|
|
binExplain.setEditable(false);
|
|
binExplain.setFocusable(false);
|
|
binExplain.setBackground(place3.getBackground());
|
|
JEditorPane binToDecExplain = new JEditorPane("text/html",expansionFontTag+"< Binary-to-decimal conversion"+"</font>");
|
|
binToDecExplain.setEditable(false);
|
|
binToDecExplain.setFocusable(false);
|
|
binToDecExplain.setBackground(place4.getBackground());
|
|
place1.add(hexExplain);
|
|
place2.add(hexToBinExplain);
|
|
place3.add(binExplain);
|
|
place4.add(binToDecExplain);
|
|
//################ 4 Grid Rows : Explanations #########################
|
|
rightPanel.add(place1);
|
|
rightPanel.add(place2);
|
|
rightPanel.add(place3);
|
|
rightPanel.add(place4);
|
|
//################ Grid Row : Decimal ##################################
|
|
rightPanel.add(decimalDisplayBox);
|
|
|
|
//######## mainPanel is vertical box, instructions get a row #################
|
|
JPanel instructionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
|
instructions = new InstructionsPane(instructionsPanel);
|
|
instructionsPanel.add(instructions);
|
|
instructionsPanel.setBorder(new TitledBorder("Instructions"));
|
|
mainPanel.add(instructionsPanel);
|
|
|
|
// Means of selecting and deselecting an attached floating point register
|
|
|
|
fpRegisters = Coprocessor1.getRegisters();
|
|
String[] registerList = new String[fpRegisters.length+1];
|
|
registerList[0] = "None";
|
|
for (int i=0; i<fpRegisters.length; i++) {
|
|
registerList[i+1] = fpRegisters[i].getName();
|
|
}
|
|
JComboBox registerSelect = new JComboBox(registerList);
|
|
registerSelect.setSelectedIndex(0); // No register attached
|
|
registerSelect.setToolTipText("Attach to selected FP register");
|
|
registerSelect.addActionListener(
|
|
new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
JComboBox cb = (JComboBox)e.getSource();
|
|
int selectedIndex = cb.getSelectedIndex();
|
|
if (isObserving()) {
|
|
deleteAsObserver();
|
|
}
|
|
if (selectedIndex==0) {
|
|
attachedRegister = null;
|
|
updateDisplays(new FlavorsOfFloat());
|
|
instructions.setText("The program is not attached to any MIPS floating point registers.");
|
|
}
|
|
else {
|
|
attachedRegister = fpRegisters[selectedIndex-1];
|
|
updateDisplays(new FlavorsOfFloat().buildOneFromInt(attachedRegister.getValue()));
|
|
if (isObserving()) {
|
|
addAsObserver();
|
|
}
|
|
instructions.setText("The program and register "+attachedRegister.getName()+" will respond to each other when MIPS program connected or running.");
|
|
}
|
|
}
|
|
});
|
|
|
|
JPanel registerPanel = new JPanel(new BorderLayout(5,5));
|
|
JPanel registerAndLabel = new JPanel();
|
|
registerAndLabel.add(new JLabel("MIPS floating point Register of interest: "));
|
|
registerAndLabel.add(registerSelect);
|
|
registerPanel.add(registerAndLabel,BorderLayout.WEST);
|
|
registerPanel.add(new JLabel(" "),BorderLayout.NORTH); // just for padding
|
|
mainPanel.add(registerPanel);
|
|
return mainPanel;
|
|
} // end of buildDisplayArea()
|
|
|
|
|
|
// If display is attached to a register then update the register value.
|
|
private synchronized void updateAnyAttachedRegister(int intValue) {
|
|
if (attachedRegister != null) {
|
|
synchronized (Globals.memoryAndRegistersLock) {
|
|
attachedRegister.setValue(intValue);
|
|
}
|
|
// HERE'S A HACK!! Want to immediately display the updated register value in MARS
|
|
// but that code was not written for event-driven update (e.g. Observer) --
|
|
// it was written to poll the registers for their values. So we force it to do so.
|
|
if (Globals.getGui() != null) {
|
|
Globals.getGui().getRegistersPane().getCoprocessor1Window().updateRegisters();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Updates all components displaying various representations of the 32 bit
|
|
// floating point value.
|
|
private void updateDisplays(FlavorsOfFloat flavors) {
|
|
int hexIndex = (flavors.hexString.charAt(0)=='0' && (flavors.hexString.charAt(1)=='x'||flavors.hexString.charAt(1)=='X')) ? 2 : 0;
|
|
hexDisplay.setText(flavors.hexString.substring(hexIndex).toUpperCase()); // lop off leading "Ox" if present
|
|
binarySignDisplay.setText(flavors.binaryString.substring(0, maxLengthBinarySign));
|
|
binaryExponentDisplay.setText(flavors.binaryString.substring(maxLengthBinarySign, maxLengthBinarySign+maxLengthBinaryExponent));
|
|
binaryFractionDisplay.setText(flavors.binaryString.substring(maxLengthBinarySign+maxLengthBinaryExponent, maxLengthBinaryTotal));
|
|
decimalDisplay.setText(flavors.decimalString);
|
|
binaryToDecimalFormulaGraphic.drawSubtractLabel(Binary.binaryStringToInt((flavors.binaryString.substring(maxLengthBinarySign, maxLengthBinarySign+maxLengthBinaryExponent))));
|
|
expansionDisplay.setText(flavors.expansionString);
|
|
updateSignificandLabel(flavors);
|
|
}
|
|
|
|
// Should be called only by those who know a register should be changed due to
|
|
// user action (reset button or Enter key on one of the input fields). Note
|
|
// this will not update the register unless we are an active Observer.
|
|
private void updateDisplaysAndRegister(FlavorsOfFloat flavors) {
|
|
updateDisplays(flavors);
|
|
if (isObserving()) {
|
|
updateAnyAttachedRegister(flavors.intValue);
|
|
}
|
|
}
|
|
|
|
// Called by updateDisplays() to determine whether or not the significand label needs
|
|
// to be changed and if so to change it. The label explains presence/absence of
|
|
// normalizing "hidden bit".
|
|
private void updateSignificandLabel(FlavorsOfFloat flavors) {
|
|
// Will change significandLabel text only if it needs to be changed...
|
|
if (flavors.binaryString.substring(maxLengthBinarySign, maxLengthBinarySign+maxLengthBinaryExponent)
|
|
.equals(zeroes.substring(maxLengthBinarySign, maxLengthBinarySign+maxLengthBinaryExponent))) {
|
|
// Will change text only if it truly is changing....
|
|
if (significandLabel.getText().indexOf("deno")<0) {
|
|
significandLabel.setText(denormalizedLabel);
|
|
}
|
|
}
|
|
else {
|
|
if (significandLabel.getText().indexOf("unde")<0) {
|
|
significandLabel.setText(normalizedLabel);
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////
|
|
/////// THE REST OF THE TOOL CONSISTS OF LITTLE PRIVATE CLASSES THAT MAKE
|
|
/////// LIFE EASIER FOR THE ABOVE CODE.
|
|
///////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class of objects that encapsulats 5 different representations of a 32 bit
|
|
// floating point value:
|
|
// string with hexadecimal value.
|
|
// String with binary value. 32 characters long.
|
|
// String with decimal float value. variable length.
|
|
// int with 32 bit representation of float value ("int bits").
|
|
// String for display only, showing formula for expanding bits to decimal.
|
|
//
|
|
private class FlavorsOfFloat {
|
|
String hexString;
|
|
String binaryString;
|
|
String decimalString;
|
|
String expansionString;
|
|
int intValue;
|
|
|
|
// Default object
|
|
private FlavorsOfFloat() {
|
|
hexString = defaultHex;
|
|
decimalString = defaultDecimal;
|
|
binaryString = defaultBinarySign+defaultBinaryExponent+defaultBinaryFraction;
|
|
expansionString = buildExpansionFromBinaryString(binaryString);
|
|
intValue = Float.floatToIntBits(Float.parseFloat(decimalString));
|
|
}
|
|
|
|
// Assign all fields given a string representing 32 bit hex value.
|
|
public FlavorsOfFloat buildOneFromHexString(String hexString) {
|
|
this.hexString = "0x" + addLeadingZeroes(
|
|
((hexString.indexOf("0X")==0 || hexString.indexOf("0x")==0)
|
|
? hexString.substring(2) : hexString), maxLengthHex);
|
|
this.binaryString = Binary.hexStringToBinaryString(this.hexString);
|
|
this.decimalString = new Float(Float.intBitsToFloat(Binary.binaryStringToInt(this.binaryString))).toString();
|
|
this.expansionString = buildExpansionFromBinaryString(this.binaryString);
|
|
this.intValue = Binary.binaryStringToInt(this.binaryString);
|
|
return this;
|
|
}
|
|
|
|
// Assign all fields given a string representing 32 bit binary value
|
|
private FlavorsOfFloat buildOneFromBinaryString() {
|
|
this.binaryString = getFullBinaryStringFromDisplays();
|
|
this.hexString = Binary.binaryStringToHexString(binaryString);
|
|
this.decimalString = new Float(Float.intBitsToFloat(Binary.binaryStringToInt(this.binaryString))).toString();
|
|
this.expansionString = buildExpansionFromBinaryString(this.binaryString);
|
|
this.intValue = Binary.binaryStringToInt(this.binaryString);
|
|
return this;
|
|
}
|
|
|
|
// Assign all fields given string representing floating point decimal value.
|
|
private FlavorsOfFloat buildOneFromDecimalString(String decimalString) {
|
|
float floatValue;
|
|
try {
|
|
floatValue = Float.parseFloat(decimalString);
|
|
}
|
|
catch (NumberFormatException nfe) {
|
|
return null;
|
|
}
|
|
this.decimalString = new Float(floatValue).toString();
|
|
this.intValue = Float.floatToIntBits(floatValue);// use floatToRawIntBits?
|
|
this.binaryString = Binary.intToBinaryString(this.intValue);
|
|
this.hexString = Binary.binaryStringToHexString(this.binaryString);
|
|
this.expansionString = buildExpansionFromBinaryString(this.binaryString);
|
|
return this;
|
|
}
|
|
|
|
// Assign all fields given int representing 32 bit representation of float value
|
|
private FlavorsOfFloat buildOneFromInt(int intValue) {
|
|
this.intValue = intValue;
|
|
this.binaryString = Binary.intToBinaryString(intValue);
|
|
this.hexString = Binary.binaryStringToHexString(this.binaryString);
|
|
this.decimalString = new Float(Float.intBitsToFloat(Binary.binaryStringToInt(this.binaryString))).toString();
|
|
this.expansionString = buildExpansionFromBinaryString(this.binaryString);
|
|
return this;
|
|
}
|
|
|
|
// Build binary expansion formula for display -- will not be editable.
|
|
public String buildExpansionFromBinaryString(String binaryString) {
|
|
int biasedExponent = Binary.binaryStringToInt(
|
|
binaryString.substring(maxLengthBinarySign,maxLengthBinarySign+maxLengthBinaryExponent));
|
|
String stringExponent = Integer.toString(biasedExponent - exponentBias);
|
|
// stringExponent length will range from 1 to 4 (e.g. "0" to "-128") characters.
|
|
// Right-pad with HTML spaces (" ") to total length 5 displayed characters.
|
|
return "<html><head></head><body>"+expansionFontTag
|
|
+ "-1<sup>"+binaryString.substring(0,maxLengthBinarySign)+"</sup> * 2<sup>"
|
|
+ stringExponent + HTMLspaces.substring(0, (5-stringExponent.length())*6)
|
|
+ "</sup> * "
|
|
+ ((biasedExponent==0) ? " ." : "<u>1</u>.")
|
|
+ binaryString.substring(maxLengthBinarySign+maxLengthBinaryExponent, maxLengthBinaryTotal)
|
|
+ " =</font></body></html>";
|
|
}
|
|
|
|
// Handy utility to concatentate the binary field values into one 32 character string
|
|
// Left-pad each field with zeroes as needed to reach its full length.
|
|
private String getFullBinaryStringFromDisplays() {
|
|
return addLeadingZeroes(binarySignDisplay.getText(), maxLengthBinarySign) +
|
|
addLeadingZeroes(binaryExponentDisplay.getText(), maxLengthBinaryExponent) +
|
|
addLeadingZeroes(binaryFractionDisplay.getText(), maxLengthBinaryFraction);
|
|
}
|
|
|
|
// Handy utility. Pads with leading zeroes to specified length, maximum 64 of 'em.
|
|
private String addLeadingZeroes(String str, int length) {
|
|
return (str.length() < length)
|
|
? zeroes.substring(0,Math.min(zeroes.length(),length-str.length()))+str
|
|
: str;
|
|
}
|
|
|
|
}
|
|
//Put here because inner class cannot have static members.
|
|
private static final String zeroes =
|
|
"0000000000000000000000000000000000000000000000000000000000000000"; //64
|
|
private static final String HTMLspaces = " ";
|
|
|
|
|
|
// NOTE: It would be nice to use InputVerifier class to verify user input
|
|
// but I want keystroke-level monitoring to assure that no invalid
|
|
// keystrokes are echoed and that maximum string length is not exceeded.
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class to handle input keystrokes for hexadecimal field
|
|
//
|
|
private class HexDisplayKeystrokeListener extends KeyAdapter {
|
|
|
|
private int digitLength; // maximum number of digits long
|
|
|
|
public HexDisplayKeystrokeListener(int length) {
|
|
digitLength = length;
|
|
}
|
|
|
|
|
|
// Process user keystroke. If not valid for the context, this
|
|
// will consume the stroke and beep.
|
|
public void keyTyped(KeyEvent e) {
|
|
JTextField source = (JTextField) e.getComponent();
|
|
if (e.getKeyChar()== KeyEvent.VK_BACK_SPACE || e.getKeyChar()== KeyEvent.VK_TAB )
|
|
return;
|
|
if (!isHexDigit(e.getKeyChar()) ||
|
|
source.getText().length()==digitLength && source.getSelectedText()==null) {
|
|
if (e.getKeyChar()!= KeyEvent.VK_ENTER && e.getKeyChar() != KeyEvent.VK_TAB) {
|
|
Toolkit.getDefaultToolkit().beep();
|
|
if (source.getText().length()==digitLength && source.getSelectedText()==null) {
|
|
instructions.setText("Maximum length of this field is "+digitLength+".");
|
|
}
|
|
else {
|
|
instructions.setText("Only digits and A-F (or a-f) are accepted in hexadecimal field.");
|
|
}
|
|
}
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// Enter key is echoed on component after keyPressed but before keyTyped?
|
|
// Consuming the VK_ENTER event in keyTyped does not suppress it but this will.
|
|
public void keyPressed(KeyEvent e) {
|
|
if (e.getKeyChar()== KeyEvent.VK_ENTER || e.getKeyChar()== KeyEvent.VK_TAB) {
|
|
updateDisplaysAndRegister(new FlavorsOfFloat().buildOneFromHexString(((JTextField)e.getSource()).getText()));
|
|
instructions.setText(defaultInstructions);
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// handy utility.
|
|
private boolean isHexDigit(char digit) {
|
|
boolean result = false;
|
|
switch (digit) {
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
|
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class to handle input keystrokes for binary field
|
|
//
|
|
private class BinaryDisplayKeystrokeListener extends KeyAdapter {
|
|
|
|
private int bitLength; // maximum number of bits permitted
|
|
|
|
public BinaryDisplayKeystrokeListener(int length) {
|
|
bitLength = length;
|
|
}
|
|
|
|
// Process user keystroke. If not valid for the context, this
|
|
// will consume the stroke and beep.
|
|
public void keyTyped(KeyEvent e) {
|
|
JTextField source = (JTextField) e.getComponent();
|
|
if (e.getKeyChar()== KeyEvent.VK_BACK_SPACE)
|
|
return;
|
|
if (!isBinaryDigit(e.getKeyChar()) ||
|
|
e.getKeyChar() == KeyEvent.VK_ENTER ||
|
|
source.getText().length()==bitLength && source.getSelectedText()==null) {
|
|
if (e.getKeyChar()!= KeyEvent.VK_ENTER) {
|
|
Toolkit.getDefaultToolkit().beep();
|
|
if (source.getText().length()==bitLength && source.getSelectedText()==null) {
|
|
instructions.setText("Maximum length of this field is "+bitLength+".");
|
|
}
|
|
else {
|
|
instructions.setText("Only 0 and 1 are accepted in binary field.");
|
|
}
|
|
}
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// Enter key is echoed on component after keyPressed but before keyTyped?
|
|
// Consuming the VK_ENTER event in keyTyped does not suppress it but this will.
|
|
public void keyPressed(KeyEvent e) {
|
|
if (e.getKeyChar()== KeyEvent.VK_ENTER) {
|
|
updateDisplaysAndRegister(new FlavorsOfFloat().buildOneFromBinaryString());
|
|
instructions.setText(defaultInstructions);
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// handy utility
|
|
private boolean isBinaryDigit(char digit) {
|
|
boolean result = false;
|
|
switch (digit) {
|
|
case '0': case '1':
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class to handle input keystrokes for decimal field
|
|
//
|
|
private class DecimalDisplayKeystokeListenter extends KeyAdapter {
|
|
|
|
// Process user keystroke. If not valid for the context, this
|
|
// will consume the stroke and beep.
|
|
public void keyTyped(KeyEvent e) {
|
|
JTextField source = (JTextField) e.getComponent();
|
|
if (e.getKeyChar()== KeyEvent.VK_BACK_SPACE)
|
|
return;
|
|
if (!isDecimalFloatDigit(e.getKeyChar())) {
|
|
if (e.getKeyChar()!= KeyEvent.VK_ENTER) {
|
|
instructions.setText("Only digits, period, signs and E (or e) are accepted in decimal field.");
|
|
Toolkit.getDefaultToolkit().beep();
|
|
}
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// Enter key is echoed on component after keyPressed but before keyTyped?
|
|
// Consuming the VK_ENTER event in keyTyped does not suppress it but this will.
|
|
public void keyPressed(KeyEvent e) {
|
|
if (e.getKeyChar()== KeyEvent.VK_ENTER) {
|
|
FlavorsOfFloat fof = new FlavorsOfFloat().buildOneFromDecimalString(((JTextField)e.getSource()).getText());
|
|
if (fof==null) {
|
|
Toolkit.getDefaultToolkit().beep();
|
|
instructions.setText("'"+((JTextField)e.getSource()).getText()+"' is not a valid floating point number.");
|
|
}
|
|
else {
|
|
updateDisplaysAndRegister(fof);
|
|
instructions.setText(defaultInstructions);
|
|
}
|
|
e.consume();
|
|
}
|
|
}
|
|
|
|
// handy utility
|
|
private boolean isDecimalFloatDigit(char digit) {
|
|
boolean result = false;
|
|
switch (digit) {
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
case '-': case '+': case '.': case 'e': case 'E':
|
|
result = true;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Use this to draw graphics visually relating the hexadecimal values
|
|
// displayed above) to the binary values (displayed below).
|
|
//
|
|
class HexToBinaryGraphicPanel extends JPanel {
|
|
|
|
// This overrides inherited JPanel method. Override is necessary to
|
|
// assure my drawn graphics get painted immediately after painting the
|
|
// underlying JPanel (see first statement).
|
|
public void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
g.setColor(Color.red);
|
|
//FontMetrics fontMetrics = hexDisplay.getGraphics().getFontMetrics();
|
|
int upperY = 0;
|
|
int lowerY = 60;
|
|
int hexColumnWidth = hexDisplay.getWidth()/hexDisplay.getColumns();
|
|
// assume all 3 binary displays use same geometry, so column width same for all.
|
|
int binaryColumnWidth = binaryFractionDisplay.getWidth()/binaryFractionDisplay.getColumns();
|
|
Polygon p;
|
|
// loop will handle the lower order 5 "nibbles" (hex digits)
|
|
for (int i=1; i<6; i++) {
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-i)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryFractionDecoratedDisplay.getX()+binaryColumnWidth*(binaryFractionDisplay.getColumns()-((i*5)-i)), lowerY);
|
|
p.addPoint(binaryFractionDecoratedDisplay.getX()+binaryColumnWidth*(binaryFractionDisplay.getColumns()-(((i*5)-i)-4)), lowerY);
|
|
g.fillPolygon(p);
|
|
}
|
|
// Nibble 5 straddles binary display of exponent and fraction.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-6)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryFractionDecoratedDisplay.getX()+binaryColumnWidth*(binaryFractionDisplay.getColumns()-20), lowerY);
|
|
p.addPoint(binaryExponentDecoratedDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-1), lowerY);
|
|
g.fillPolygon(p);
|
|
// Nibble 6 maps to binary display of exponent.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-7)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryExponentDecoratedDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-1), lowerY);
|
|
p.addPoint(binaryExponentDecoratedDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-5), lowerY);
|
|
g.fillPolygon(p);
|
|
// Nibble 7 straddles binary display of sign and exponent.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-8)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryExponentDecoratedDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-5), lowerY);
|
|
p.addPoint(binarySignDecoratedDisplay.getX(), lowerY);
|
|
g.fillPolygon(p);
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Panel to hold arrows explaining transformation of binary represntation
|
|
// into formula for calculating decimal value.
|
|
//
|
|
class BinaryToDecimalFormulaGraphic extends JPanel {
|
|
final String subtractLabelTrailer = " - 127";
|
|
final int arrowHeadOffset = 5;
|
|
final int lowerY = 0;
|
|
final int upperY = 50;
|
|
int centerX, exponentCenterX;
|
|
int subtractLabelWidth, subtractLabelHeight;
|
|
int centerY = (upperY-lowerY)/2;
|
|
int upperYArrowHead = upperY-arrowHeadOffset;
|
|
int currentExponent = Binary.binaryStringToInt(defaultBinaryExponent);
|
|
public void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
// Arrow down from binary sign field
|
|
centerX = binarySignDecoratedDisplay.getX()+binarySignDecoratedDisplay.getWidth()/2;
|
|
g.drawLine(centerX,lowerY,centerX,upperY);
|
|
g.drawLine(centerX-arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
g.drawLine(centerX+arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
// Arrow down from binary exponent field
|
|
centerX = binaryExponentDecoratedDisplay.getX()+binaryExponentDecoratedDisplay.getWidth()/2;
|
|
g.drawLine(centerX,lowerY,centerX,upperY);
|
|
g.drawLine(centerX-arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
g.drawLine(centerX+arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
// Label on exponent arrow. The two assignments serve to initialize two
|
|
// instance variables that are used by drawSubtractLabel(). They are
|
|
// initialized here because they cannot be initialized sooner AND because
|
|
// the drawSubtractLabel() method will later be called by updateDisplays(),
|
|
// an outsider which has no other access to that information. Once set they
|
|
// do not change so it does no harm that they are "re-initialized" each time
|
|
// this method is called (which occurs only upon startup and when this portion
|
|
// of the GUI needs to be repainted).
|
|
exponentCenterX = centerX;
|
|
subtractLabelHeight = g.getFontMetrics().getHeight();
|
|
drawSubtractLabel(g, buildSubtractLabel(currentExponent));
|
|
// Arrow down from binary fraction field
|
|
centerX = binaryFractionDecoratedDisplay.getX()+binaryFractionDecoratedDisplay.getWidth()/2;
|
|
g.drawLine(centerX,lowerY,centerX,upperY);
|
|
g.drawLine(centerX-arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
g.drawLine(centerX+arrowHeadOffset,upperYArrowHead,centerX,upperY);
|
|
}
|
|
|
|
// To be used only by "outsiders" to update the display of the exponent and bias.
|
|
public void drawSubtractLabel(int exponent) {
|
|
if (exponent != currentExponent) { // no need to redraw if it hasn't changed...
|
|
currentExponent = exponent;
|
|
drawSubtractLabel(getGraphics(), buildSubtractLabel(exponent));
|
|
}
|
|
}
|
|
|
|
// Is called by both drawSubtractLabel() just above and by paintComponent().
|
|
private void drawSubtractLabel(Graphics g, String label) {
|
|
// Clear the existing subtract label. The "+2" overwrites the arrow at initial paint when label width is 0.
|
|
// Originally used "clearRect()" but changed to "fillRect()" with background color, because when running
|
|
// as a MarsTool it would clear with a different color.
|
|
Color saved = g.getColor();
|
|
g.setColor(binaryToDecimalFormulaGraphic.getBackground());
|
|
g.fillRect(exponentCenterX-subtractLabelWidth/2,centerY-subtractLabelHeight/2,subtractLabelWidth+2,subtractLabelHeight);
|
|
g.setColor(saved);
|
|
subtractLabelWidth = g.getFontMetrics().stringWidth(label);
|
|
g.drawString(label,exponentCenterX-subtractLabelWidth/2,centerY+subtractLabelHeight/2-3); // -3 makes it more visually appealing
|
|
}
|
|
|
|
// format the label for a given integer exponent value...
|
|
private String buildSubtractLabel(int value) {
|
|
return Integer.toString(value) + subtractLabelTrailer;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Handly little class defined only to allow client to use "setText()" without
|
|
// needing to know how/whether the text needs to be formatted. This one is
|
|
// used to display instructions.
|
|
|
|
class InstructionsPane extends JLabel {
|
|
|
|
InstructionsPane(Component parent) {
|
|
super(defaultInstructions);
|
|
this.setFont(instructionsFont);
|
|
this.setBackground(parent.getBackground());
|
|
}
|
|
|
|
public void setText(String text) {
|
|
super.setText(text);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Use this to draw custom background in the binary fraction display.
|
|
//
|
|
class BinaryFractionDisplayTextField extends JTextField {
|
|
|
|
public BinaryFractionDisplayTextField(String value, int columns) {
|
|
super(value,columns);
|
|
}
|
|
|
|
// This overrides inherited JPanel method. Override is necessary to
|
|
// assure my drawn graphics get painted immediately after painting the
|
|
// underlying JPanel (see first statement).
|
|
public void paintComponent(Graphics g) {
|
|
super.paintComponent(g);
|
|
// The code below is commented out because I decided to abandon
|
|
// my effort to provide "striped" background that alternates colors
|
|
// for every 4 characters (bits) of the display. This would make
|
|
// the correspondence between bits and hex digits very clear.
|
|
// NOTE: this is the only reason for subclassing JTextField.
|
|
|
|
/*
|
|
int columnWidth = getWidth()/getColumns();
|
|
Color shadedColor = Color.red;
|
|
Polygon p;
|
|
// loop will handle the lower order 5 "nibbles" (hex digits)
|
|
for (int i=3; i<20; i+=8) {
|
|
p = new Polygon();
|
|
p.addPoint(getX()+columnWidth*i, getY());
|
|
p.addPoint(getX()+columnWidth*i, getY()+getHeight());
|
|
p.addPoint(getX()+columnWidth*(i+4), getY()+getHeight());
|
|
p.addPoint(getX()+columnWidth*(i+4), getY());
|
|
// System.out.println("Polygon vertices are:"+
|
|
// " ("+(getX()+columnWidth*i) +","+getY() +") "+
|
|
// " ("+(getX()+columnWidth*i) +","+(getY()+getHeight())+") "+
|
|
// " ("+(getX()+columnWidth*(i+4))+","+(getY()+getHeight())+") "+
|
|
// " ("+(getX()+columnWidth*(i+4))+","+getY() +") "
|
|
// );
|
|
g.setColor(shadedColor);
|
|
g.fillPolygon(p);
|
|
}*/
|
|
/*
|
|
// Nibble 5 straddles binary display of exponent and fraction.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-6)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryFractionDisplay.getX()+binaryColumnWidth*(binaryFractionDisplay.getColumns()-20), lowerY);
|
|
p.addPoint(binaryExponentDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-1), lowerY);
|
|
g.fillPolygon(p);
|
|
// Nibble 6 maps to binary display of exponent.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-7)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryExponentDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-1), lowerY);
|
|
p.addPoint(binaryExponentDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-5), lowerY);
|
|
g.fillPolygon(p);
|
|
// Nibble 7 straddles binary display of sign and exponent.
|
|
p = new Polygon();
|
|
p.addPoint(hexDisplay.getX()+hexColumnWidth*(hexDisplay.getColumns()-8)+hexColumnWidth/2, upperY);
|
|
p.addPoint(binaryExponentDisplay.getX()+binaryColumnWidth*(binaryExponentDisplay.getColumns()-5), lowerY);
|
|
p.addPoint(binarySignDisplay.getX(), lowerY);
|
|
g.fillPolygon(p);
|
|
*/
|
|
}
|
|
}
|
|
|
|
} |