Java tutorial
/******************************************************************** Copyright (c) 1996 Artima Software Company. All Rights Reserved. * Permission to use, copy, modify, and distribute this software * and its documentation for EVALUATION purposes only * is hereby granted provided that this copyright notice * appears in all copies. "Evaluation purposes" are any uses which * do not constitute the sale, sharing, or redistribution of this * software with or to any other persons in any medium. * * ARTIMA SOFTWARE COMPANY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT * THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ARTIMA SOFTWARE COMPANY * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. PROJECT: JavaWorld MODULE: Under The Hood FILE: ExposedFloat.java AUTHOR: Bill Venners, August 1996 DESCRIPTION: This file contains all the code for the Floating Point Viewer applet, named Exposed Float, that accompanies the Under The Hood article titled, "Floating Point Arithmetic". As I developed this applet I had every class in a separate file. I combined them in one file here to make it easier to download. *********************************************************************/ import java.awt.*; import java.applet.*; public class ExposedFloat extends Applet { private Label binaryField; private Label signField; private Label exponentField; private Label mantissaField; private Label hexField; private Label base2Field; private Label base10Field; private float value; private final String titleString = "EXPOSED FLOAT"; private final String binaryString = "binary"; private final String signString = "sign"; private final String exponentString = "exponent"; private final String mantissaString = "mantissa"; private final String hexString = "hex"; private final String base10String = "radix 10"; private final String base2String = "radix 2"; private final String incrementButtonString = "++"; private final String decrementButtonString = "--"; private final String multByZeroButtonString = "*=(0)"; private final String piButtonString = "Pi"; private final String positiveInfinityButtonString = "+Inf"; private final String negativeInfinityButtonString = "-Inf"; private final String maximumButtonString = "Max"; private final String minimumButtonString = "Min"; private final String notANumberButtonString = "NaN"; private final String changeSignButtonString = "*=(-1)"; private final String doubleButtonString = "*=(2)"; private final String halveButtonString = "/=(2)"; private final String notANumberString = "Not A Number"; private final String positiveInfinityString = "+Infinity"; private final String negativeInfinityString = "-Infinity"; Button maximumButton = new Button(maximumButtonString); Button minimumButton = new Button(minimumButtonString); Button positiveInfinityButton = new Button(positiveInfinityButtonString); Button negativeInfinityButton = new Button(negativeInfinityButtonString); Button piButton = new Button(piButtonString); Button notANumberButton = new Button(notANumberButtonString); public void init() { Panel buttonPanel = new PanelWithInsets(0, 0, 0, 0); buttonPanel.setLayout(new GridLayout(6, 2, 5, 5)); buttonPanel.add(maximumButton); buttonPanel.add(minimumButton); buttonPanel.add(positiveInfinityButton); buttonPanel.add(negativeInfinityButton); buttonPanel.add(piButton); buttonPanel.add(notANumberButton); buttonPanel.add(new Button(multByZeroButtonString)); buttonPanel.add(new Button(changeSignButtonString)); buttonPanel.add(new Button(doubleButtonString)); buttonPanel.add(new Button(halveButtonString)); buttonPanel.add(new RepeaterButton(incrementButtonString)); buttonPanel.add(new RepeaterButton(decrementButtonString)); binaryField = new Label("00000000000000000000000000000000"); signField = new Label("0"); exponentField = new Label("00000000"); mantissaField = new Label("000000000000000000000000"); hexField = new Label("00000000"); base2Field = new Label("0"); base10Field = new Label("0"); Font fieldFont = new Font("TimesRoman", Font.PLAIN, 12); binaryField.setFont(fieldFont); signField.setFont(fieldFont); exponentField.setFont(fieldFont); mantissaField.setFont(fieldFont); hexField.setFont(fieldFont); base2Field.setFont(fieldFont); base10Field.setFont(fieldFont); Panel numberPanel = new Panel(); numberPanel.setBackground(Color.white); numberPanel.setLayout(new GridLayout(7, 1)); numberPanel.add(signField); numberPanel.add(exponentField); numberPanel.add(mantissaField); Panel binaryPanel = new Panel(); binaryPanel.setLayout(new BorderLayout()); binaryPanel.add("Center", binaryField); numberPanel.add(binaryPanel); Panel hexPanel = new Panel(); hexPanel.setLayout(new BorderLayout()); hexPanel.add("Center", hexField); numberPanel.add(hexPanel); numberPanel.add(base2Field); numberPanel.add(base10Field); Panel labelPanel = new Panel(); labelPanel.setBackground(Color.white); labelPanel.setLayout(new GridLayout(7, 1)); Font labelFont = new Font("Helvetica", Font.ITALIC, 11); Label label = new Label(signString, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(exponentString, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(mantissaString, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(binaryString, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(hexString, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(base2String, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); label = new Label(base10String, Label.CENTER); label.setFont(labelFont); labelPanel.add(label); Panel dataPanel = new Panel(); dataPanel.setLayout(new BorderLayout()); dataPanel.add("West", labelPanel); dataPanel.add("Center", numberPanel); ColoredLabel title = new ColoredLabel(titleString, Label.CENTER, Color.cyan); title.setFont(new Font("Helvetica", Font.BOLD, 12)); setBackground(Color.green); setLayout(new BorderLayout(5, 5)); add("North", title); add("West", buttonPanel); add("Center", dataPanel); } public boolean action(Event evt, Object arg) { if (evt.target instanceof Button) { String bname = (String) arg; if (bname.equals(incrementButtonString)) { ++value; } else if (bname.equals(decrementButtonString)) { --value; } else if (bname.equals(multByZeroButtonString)) { value *= (float) 0.0; } else if (bname.equals(piButtonString)) { value = (float) Math.PI; } else if (bname.equals(positiveInfinityButtonString)) { value = Float.POSITIVE_INFINITY; } else if (bname.equals(negativeInfinityButtonString)) { value = Float.NEGATIVE_INFINITY; } else if (bname.equals(maximumButtonString)) { value = Float.MAX_VALUE; } else if (bname.equals(minimumButtonString)) { value = Float.MIN_VALUE; } else if (bname.equals(notANumberButtonString)) { value = Float.NaN; } else if (bname.equals(changeSignButtonString)) { value *= -1.0; } else if (bname.equals(doubleButtonString)) { value *= 2.0; } else if (bname.equals(halveButtonString)) { value /= 2.0; } updateNumberFields(); enableDisableButton(maximumButton, Float.MAX_VALUE); enableDisableButton(minimumButton, Float.MIN_VALUE); enableDisableButton(positiveInfinityButton, Float.POSITIVE_INFINITY); enableDisableButton(negativeInfinityButton, Float.NEGATIVE_INFINITY); enableDisableButton(piButton, (float) Math.PI); enableDisableButton(notANumberButton, Float.NaN); if (!notANumberButton.isEnabled()) { if (!Float.isNaN(value)) { notANumberButton.enable(); } } else if (Float.isNaN(value)) { notANumberButton.disable(); } } return true; } void enableDisableButton(Button b, float val) { if (!b.isEnabled()) { if (value != val) { b.enable(); } } else if (value == val) { b.disable(); } } void updateNumberFields() { int intBits = Float.floatToIntBits(value); if (Float.isNaN(value)) { base10Field.setText(notANumberString); } else if (Float.isInfinite(value)) { if ((intBits >>> 31) == 1) { // This is a negative infinity base10Field.setText(negativeInfinityString); } else { // This is a positive infinity base10Field.setText(positiveInfinityString); } } else if (intBits == (int) 0x80000000) { base10Field.setText("-0"); } else { base10Field.setText(Float.toString(value)); } int v = intBits; StringBuffer buf = new StringBuffer(); for (int i = 0; i < 8; ++i) { // Get lowest bit int remainder = v & 0xf; // Convert bit to a character and insert it into the beginning of the string switch (remainder) { case 0: buf.insert(0, "0"); break; case 1: buf.insert(0, "1"); break; case 2: buf.insert(0, "2"); break; case 3: buf.insert(0, "3"); break; case 4: buf.insert(0, "4"); break; case 5: buf.insert(0, "5"); break; case 6: buf.insert(0, "6"); break; case 7: buf.insert(0, "7"); break; case 8: buf.insert(0, "8"); break; case 9: buf.insert(0, "9"); break; case 10: buf.insert(0, "a"); break; case 11: buf.insert(0, "b"); break; case 12: buf.insert(0, "c"); break; case 13: buf.insert(0, "d"); break; case 14: buf.insert(0, "e"); break; case 15: buf.insert(0, "f"); break; } // Shift the int to the right one bit v >>>= 4; } hexField.setText(buf.toString()); v = intBits; buf.setLength(0); for (int i = 0; i < 32; ++i) { // Get lowest bit int remainder = v & 0x1; // Convert bit to a character and insert it into the beginning of the string if (remainder == 0) { buf.insert(0, "0"); } else { buf.insert(0, "1"); } // Shift the int to the right one bit v >>>= 1; } binaryField.setText(buf.toString()); if (intBits < 0) { signField.setText("1"); } else { signField.setText("0"); } v = intBits >> 23; buf.setLength(0); for (int i = 0; i < 8; ++i) { // Get lowest bit int remainder = v & 0x1; // Convert bit to a character and insert it into the beginning of the string if (remainder == 0) { buf.insert(0, "0"); } else { buf.insert(0, "1"); } // Shift the int to the right one bit v >>>= 1; } exponentField.setText(buf.toString()); // Do the mantissa v = intBits; buf.setLength(0); for (int i = 0; i < 23; ++i) { // Get lowest bit int remainder = v & 0x1; // Convert bit to a character and insert it into the beginning of the string if (remainder == 0) { buf.insert(0, "0"); } else { buf.insert(0, "1"); } // Shift the int to the right one bit v >>>= 1; } if (((intBits >> 23) & 0xff) == 0) { // This is a denormalized number, first bit is 0 buf.insert(0, "0"); } else { // This is a normalized number, first bit is 1 buf.insert(0, "1"); } mantissaField.setText(buf.toString()); // Print out a denormalized base 2 version. buf.setLength(0); if (Float.isNaN(value)) { buf.append(notANumberString); } else if (Float.isInfinite(value)) { if ((intBits >>> 31) == 1) { // This is a negative infinity buf.append(negativeInfinityString); } else { // This is a positive infinity buf.append(positiveInfinityString); } } else { if ((intBits >>> 31) == 1) { // This is a negative number buf.append("-"); } // Convert mantissa to int. v = (intBits & 0x007fffff); if (((intBits >> 23) & 0xff) != 0) { // Set bit 23 if the number is normalized v |= 0x00800000; } buf.append(v); // print out the exponent v = (intBits >> 23) & 0xff; if (v != 150 && intBits != 0 && intBits != (int) 0x80000000) { if (v != 0) { // regular normalized number buf.append("e" + (v - 150)); } else { // denormalized number buf.append("e-149"); } } } base2Field.setText(buf.toString()); } public Insets insets() { return new Insets(5, 5, 5, 5); } } // I used this class because I can't seem to set the background color of // a label. I only want a label, but I want the backgound to be gray. class ColoredLabel extends Panel { private Label theLabel; ColoredLabel(String label, int alignment, Color color) { setLayout(new GridLayout(1, 1)); setBackground(color); theLabel = new Label(label, alignment); add(theLabel); } public void setLabelText(String s) { theLabel.setText(s); } public Insets insets() { return new Insets(0, 0, 0, 0); } } class GrayButton extends Button { GrayButton(String label) { super(label); setBackground(Color.lightGray); } } class PanelWithInsets extends Panel { private int top; private int left; private int bottom; private int right; PanelWithInsets(int t, int l, int b, int r) { top = t; left = l; bottom = b; right = r; } PanelWithInsets() { top = 5; left = 5; bottom = 5; right = 5; } public Insets insets() { return new Insets(top, left, bottom, right); } } class RepeaterButton extends GrayButton { RepeaterButton(String label) { super(label); } }