Mega Code Archive

 
Categories / Java / Development Class
 

Floating Point Arithmetic

/******************************************************************** 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);     } }