# 3.2 Denormalized Numbers

 Java Number Cruncher: The Java Programmer's Guide to Numerical Computing By Ronald  Mak Table of Contents Chapter  3.   The Floating-Point Standard

3.2 Denormalized Numbers

Why do we need denormalized numbers?

Recall that, in Chapter 1, we observed that the floating-point numbers are not evenly distributed along the number line. They are densest near 0, and the size of the gaps between successive numbers increases exponentially as the exponent value increases . In the IEEE 754 standard, the base of the exponent is 2, and so the gaps double in size with each increment of the exponent value.

The smallest positive normalized float value has

Then

and the significand is binary 1.00000000000000000000000. The value is

Without the denormalized numbers, the next smaller number is 0. When computing with extremely small numbers, this gap causes a "flush to zero."

The largest possible denormalized float value has

and the significand is binary 0.11111111111111111111111. Its value is

So the largest possible denormalized float value is slightly less than the smallest positive normalized float value; since we already know that the smallest possible positive denormalized float value is approximately 1.4 x 10 - 45 , the denormalized values help fill in the gap between 0 and the smallest possible normalized float value.

Thus, Java supports the more elegant "gradual underflow." As computed values get smaller and smaller, they become denormalized. Thus, instead of having the values abruptly flush to zero, there is a smoother approach to 0.

 Top

 Java Number Cruncher: The Java Programmer's Guide to Numerical Computing By Ronald  Mak Table of Contents Chapter  3.   The Floating-Point Standard

### 3.3 Decomposing Floating-Point Numbers

Listing 3-0a shows interface IEEE754Constants in package numbercruncher. mathutils. The interface defines several constants related to the IEEE 754 standard.

##### Listing 3-0a Interface IEEE754Constants for constants related to the IEEE 754 standard.
```package numbercruncher.mathutils;

/**
* Constants related to the IEEE 754 standard.
*/
public interface IEEE754Constants
{
static final int FLOAT_SIGN_INDEX         =    0;
static final int FLOAT_SIGN_SIZE          =    1;
static final int FLOAT_EXPONENT_INDEX     =    1;
static final int FLOAT_EXPONENT_SIZE      =    8;
static final int FLOAT_EXPONENT_RESERVED  =  255;
static final int FLOAT_EXPONENT_BIAS      =  127;
static final int FLOAT_FRACTION_INDEX     =    9;
static final int FLOAT_FRACTION_SIZE      =   23;

static final int DOUBLE_SIGN_INDEX        =    0;
static final int DOUBLE_SIGN_SIZE         =    1;
static final int DOUBLE_EXPONENT_INDEX    =    1;
static final int DOUBLE_EXPONENT_SIZE     =   11;
static final int DOUBLE_EXPONENT_RESERVED = 2047;
static final int DOUBLE_EXPONENT_BIAS     = 1023;
static final int DOUBLE_FRACTION_INDEX    =   12;
static final int DOUBLE_FRACTION_SIZE     =   52;
}
```

Listing 3-0b shows class IEEE754 in the numbercruncher.mathutils package. This class has constructors that decompose a floating-point number into its constituent parts according to the IEEE 754 standard, as well as constructors to reconstitute a floating-point number from its parts . It also includes a print() method, which prints the parts of a floating-point number.

##### Listing 3-0b Class IEEE754, which decomposes and reconstitutes floating-point numbers according to the IEEE 754 standard.
```package numbercruncher.mathutils;

/**
* Decompose a floating-point value into its parts
* according to the IEEE 754 standard.
*/
public class IEEE754 implements IEEE754Constants
{
/** sign bit as a string */         private String signBit;
/** exponent bits as a string */    private String exponentBits;
/** fraction bits as a string */    private String fractionBits;
/** implied bit as a string */      private String impliedBit;

/** biased exponent value */    private int  biased;
/** fraction value */           private long fraction;

/** exponent bias */            private int bias;

/** float number value */       private float  floatValue;
/** double number value */      private double doubleValue;

/** true if number
value is zero */            private boolean isZero;
/** true if reserved
exponent value */           private boolean isReserved;
/** true if number type
is double */                private boolean isDouble;
/** true if denormalized
number value */             private boolean isDenormalized;

//--------------//
// Constructors //
//--------------//

/**
* Constructor. Decompose a float value.
* @param value the float value to decompose
*/
public IEEE754(float value)
{
// Convert the value to a character array of '0' and '1'.
char bits[] = toCharBitArray(Float.floatToIntBits(value), 32);

floatValue = value;
isDouble   = false;

decompose(bits,
FLOAT_EXPONENT_BIAS,  FLOAT_EXPONENT_RESERVED,
FLOAT_SIGN_INDEX,     FLOAT_SIGN_SIZE,
FLOAT_EXPONENT_INDEX, FLOAT_EXPONENT_SIZE,
FLOAT_FRACTION_INDEX, FLOAT_FRACTION_SIZE);
}

/**
* Constructor. Decompose a double value.
* @param value the double-precision value to decompose
*/
public IEEE754(double value)
{
// Convert the value to a character array of '0' and '1'.
char bits[] = toCharBitArray(Double.doubleToLongBits(value), 64);

doubleValue = value;
isDouble    = true;

decompose(bits,
DOUBLE_EXPONENT_BIAS,  DOUBLE_EXPONENT_RESERVED,
DOUBLE_SIGN_INDEX,     DOUBLE_SIGN_SIZE,
DOUBLE_EXPONENT_INDEX, DOUBLE_EXPONENT_SIZE,
DOUBLE_FRACTION_INDEX, DOUBLE_FRACTION_SIZE);
}

/**
* Constructor. Reconstitute a float value.
* @param sign the sign bit value, 0 or 1
* @param biasedExponent the biased exponent value, 0..255
* @param fraction the fraction bits
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public IEEE754(int sign, int biasedExponent, FloatFraction fraction)
throws Exception
{
// Check the sign.
if ((sign != 0) && (sign != 1)) {
throw new Exception("Invalid sign bit.");
}

validateFloatBiasedExponent(biasedExponent);

// Consolidate the parts.  First the sign ...
int intBits = sign;

// ... then the biased exponent value ...
intBits <<= FLOAT_EXPONENT_SIZE;
intBits += biasedExponent;

// ... and finally the fraction value.
intBits <<= FLOAT_FRACTION_SIZE;
intBits += fraction.toInt();

// Convert to the float value.
floatValue = Float.intBitsToFloat(intBits);
isDouble   = false;

// Convert the value to a character array of '0' and '1'.
char bits[] = toCharBitArray(intBits, 32);

decompose(bits,
FLOAT_EXPONENT_BIAS,  FLOAT_EXPONENT_RESERVED,
FLOAT_SIGN_INDEX,     FLOAT_SIGN_SIZE,
FLOAT_EXPONENT_INDEX, FLOAT_EXPONENT_SIZE,
FLOAT_FRACTION_INDEX, FLOAT_FRACTION_SIZE);
}

/**
* Constructor. Reconstitute a double value.
* @param sign the sign bit value, 0 or 1
* @param biasedExponent the biased exponent value, 0..2047
* @param fraction the fraction bits
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public IEEE754(int sign, int biasedExponent, DoubleFraction fraction)
throws Exception
{
// Check the sign.
if ((sign != 0) && (sign != 1)) {
throw new Exception("Invalid sign bit.");
}

validateDoubleBiasedExponent(biasedExponent);

// Consolidate the parts.  First the sign ...
long longBits = sign;

// ... then the biased exponent value ...
longBits <<= DOUBLE_EXPONENT_SIZE;
longBits += biasedExponent;

// ... and finally the fraction value.
longBits <<= DOUBLE_FRACTION_SIZE;
longBits += fraction.toLong();

// Convert to the double value.
doubleValue = Double.longBitsToDouble(longBits);
isDouble    = true;

// Convert the value to a character array of '0' and '1'.
char bits[] = toCharBitArray(longBits, 64);

decompose(bits,
DOUBLE_EXPONENT_BIAS,  DOUBLE_EXPONENT_RESERVED,
DOUBLE_SIGN_INDEX,     DOUBLE_SIGN_SIZE,
DOUBLE_EXPONENT_INDEX, DOUBLE_EXPONENT_SIZE,
DOUBLE_FRACTION_INDEX, DOUBLE_FRACTION_SIZE);
}

//-------------------------//
// Methods to return parts //
//-------------------------//

/**
* Return the float value.
* @return the float value
*/
public float floatValue() { return floatValue; }

/**
* Return the double value.
* @return the double value
*/
public double doubleValue() { return doubleValue; }

/**
* Return the biased value of the exponent.
* @return the unbiased exponent value
*/
public int biasedExponent() { return biased; }

/**
* Return the unbiased value of the exponent.
* @return the unbiased exponent value
*/
public int unbiasedExponent()
{
return isDenormalized ? -bias + 1
: biased - bias;
}

/**
* Return the sign as a string of '0' and '1'.
* @return the string
*/
public String signBit() { return signBit; }

/**
* Return the exponent as a string of '0' and '1'.
* @return the string
*/
public String exponentBits() { return exponentBits; }

/**
* Return the fraction as a string of '0' and '1'.
* @return the string
*/
public String fractionBits() { return fractionBits; }

/**
* Return the significand as a string of '0', '1' and '.'.
* @return the string
*/
public String significandBits()
{
return impliedBit + "." + fractionBits;
}

/**
* Return whether or not the value is zero.
* @return true if zero, else false
*/
public boolean isZero() { return isZero; }

/**
* Return whether or not the value is a double.
* @return true if a double, else false
*/
public boolean isDouble() { return isDouble; }

/**
* Return whether or not the value is denormalized.
* @return true if denormalized, else false
*/
public boolean isDenormalized() { return isDenormalized; }

/**
* Return whether or not the exponent value is reserved.
* @return true if reserved, else false
*/
public boolean isExponentReserved() { return isReserved; }

//-----------------------//
// Decomposition methods //
//-----------------------//

/**
* Convert a long value into a character array of '0' and '1'
* that represents the value in base 2.
* @param value the long value
* @param size the array size
* @return the character array
*/
private static char[] toCharBitArray(long value, int size)
{
char bits[] = new char[size];

// Convert each bit from right to left.
for (int i = size-1; i >= 0; = -i) {
bits[i] = (value & 1) == 0 ? '0' : '1';
value >>>= 1;
}

return bits;
}

/**
* Decompose a floating-point value into its parts.
* @param bits the character array of '0' and '1'
*             that represents the value in base 2
* @param bias the exponent bias value
* @param reserved the reserved exponent value (other than 0)
* @param signIndex the index of the sign bit
* @param signSize the size  of the sign bit
* @param exponentIndex the index of the exponent
* @param exponentSize the size  of the exponent
* @param fractionIndex the index of the fraction
* @param fractionSize the size  of the fraction
*/
private void decompose(char bits[],
int bias,          int reserved,
int signIndex,     int signSize,
int exponentIndex, int exponentSize,
int fractionIndex, int fractionSize)
{
this.bias = bias;

// Extract the individual parts as strings of '0' and '1'.
signBit       = new String(bits, signIndex,     signSize);
exponentBits  = new String(bits, exponentIndex, exponentSize);
fractionBits  = new String(bits, fractionIndex, fractionSize);

try {
biased   = Integer.parseInt(exponentBits, 2);
fraction = Long.parseLong(fractionBits, 2);
}
catch(NumberFormatException ex) {}

isZero         = (biased == 0) && (fraction == 0);
isDenormalized = (biased == 0) && (fraction != 0);
isReserved     = (biased == reserved);

impliedBit = isDenormalized  isZero  isReserved ? "0" : "1";
}

/**
* Print the decomposed parts of the value.
*/
public void print()
{
System.out.println("------------------------------");

// Print the value.
if (isDouble()) {
System.out.println("double value = " + doubleValue());
}
else {
System.out.println("float value = " + floatValue());
}

// Print the sign.
System.out.print("sign = " + signBit());

// Print the bit representation of the exponent and its
// biased and unbiased values.  Indicate whether the value
// is denormalized, or whether the exponent is reserved.
System.out.print(", exponent = " + exponentBits() +
" (biased = " + biasedExponent());

if (isZero()) {
System.out.println(", zero)");
}
else if (isExponentReserved()) {
System.out.println(", reserved)");
}
else if (isDenormalized()) {
System.out.println(", denormalized, use " +
unbiasedExponent() + ")");
}
else {
System.out.println(", normalized, unbiased = " +
unbiasedExponent() + ")");
}
// Print the significand.
System.out.println("significand = " + significandBits());
}

//------------------------------- //
// Compute and validate exponents //
//------------------------------- //

/**
* Compute the value of the float biased exponent
* given the unbiased value.
* @param unbiased the unbiased exponent value
* @return the biased exponent value
*/
public static int toFloatBiasedExponent(int unbiased)
{
return unbiased + FLOAT_EXPONENT_BIAS;
}

/**
* Compute the value of the float unbiased exponent
* given the biased value.
* @param biased the biased exponent value
* @return the unbiased exponent value
*/
public static int toFloatUnbiasedExponent(int biased)
{
return biased == 0 ? -FLOAT_EXPONENT_BIAS + 1
: biased - FLOAT_EXPONENT_BIAS;
}

/**
* Compute the value of the double biased exponent
* given the unbiased value.
* @param unbiased the unbiased exponent value
* @return the biased exponent value
*/
public static int toDoubleBiasedExponent(int unbiased)
{
return unbiased + DOUBLE_EXPONENT_BIAS;
}

/**
* Compute the value of the double unbiased exponent
* given the biased value.
* @param biased the biased exponent value
* @return the unbiased exponent value
*/
public static int toDoubleUnbiasedExponent(int biased)
{
return biased == 0 ? -DOUBLE_EXPONENT_BIAS + 1
: biased - DOUBLE_EXPONENT_BIAS;
}

/**
* Validate the value of the float biased exponent value.
* @param biased the biased exponent value
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public static void validateFloatBiasedExponent(int biased)
throws Exception
{
if ((biased < 0)
(biased > FLOAT_EXPONENT_RESERVED)) {
throw new Exception("The biased exponent value should be " +
"0 through " + FLOAT_EXPONENT_RESERVED +
".");
}
}

/**
* Validate the value of the float unbiased exponent value.
* @param biased the unbiased exponent value
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public static void validateFloatUnbiasedExponent(int unbiased)
throws Exception
{
if ((unbiased < -FLOAT_EXPONENT_BIAS + 1)
(unbiased > FLOAT_EXPONENT_BIAS)) {
throw new Exception("The unbiased exponent value should be " +
-(FLOAT_EXPONENT_BIAS - 1) + " through " +
FLOAT_EXPONENT_BIAS + ".");
}
}

/**
* Validate the value of the double biased exponent value.
* @param biased the biased exponent value
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public static void validateDoubleBiasedExponent(int biased)
throws Exception
{
if ((biased < 0)
(biased > DOUBLE_EXPONENT_RESERVED)) {
throw new Exception("The biased exponent value should be " +
"0 through " +
DOUBLE_EXPONENT_RESERVED + ".");
}
}

/**
* Validate the value of the double unbiased exponent value.
* @param biased the unbiased exponent value
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public static void validateDoubleUnbiasedExponent(int unbiased)
throws Exception
{
if ((unbiased < -DOUBLE_EXPONENT_BIAS + 1)
(unbiased > DOUBLE_EXPONENT_BIAS)) {
throw new Exception("The unbiased exponent value should be " +
-(DOUBLE_EXPONENT_BIAS - 1) +
" through " +
DOUBLE_EXPONENT_BIAS + ".");
}
}

//----------------------------- //
// Nested decomposition classes //
//----------------------------- //

/**
* IEEE 754 exception.
*/
public static class Exception extends java.lang.Exception
{
public Exception(String message) { super(message); }
}

/**
* Abstract base class for the IEEE 754 part classes.
*/
private static abstract class Part
{
/** the part buffer */  private StringBuffer part;

/**
* Constructor.
* @param size the bit size of the part
* @param bits the string of character bits '0' and '1'
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
private Part(int size, String bits) throws Exception
{
if (size <= 0) {
throw new Exception("Invalid part size: " + part);
}

int length = bits.length();
part = new StringBuffer(size);

// String length matches part size.
if (length == size) {
part.append(bits);
validate();
}

// String length < part size:  Pad with '0'.
else if (length < size) {
part.append(bits);
validate();
for (int i = length; i < size; ++i) part.append('0');
}

// String length > part size:  Truncate at the right end.
else {
part.append(bits.substring(0, size));
validate();
}
}

/**
* Convert the part to an integer value.
* @return the integer value
* @throws numbercruncher.mathutils.IEEE754.Exception if the
*         binary number format is invalid
*/
protected int toInt() throws Exception
{
try {
return Integer.parseInt(part.toString(), 2);
}
catch(NumberFormatException ex) {
throw new Exception("Invalid binary number format: " +
part.toString());
}
}

/**
* Convert the part to an long value.
* @return the long value
* @throws numbercruncher.mathutils.IEEE754.Exception if the
*         binary number format is invalid
*/
protected long toLong() throws Exception
{
try {
return Long.parseLong(part.toString(), 2);
}
catch(NumberFormatException ex) {
throw new Exception("Invalid binary number format: " +
part.toString());
}
}

/**
* Return the part as a string of characters '0' and '1'.
*/
public String toString() { return part.toString(); }

/**
* Validate that the part consists only of '0' and '1'.
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
private void validate() throws Exception
{
int length = part.length();

for (int i = 0; i < length; ++i) {
char bit = part.charAt(i);
if ((bit != '0') && (bit != '1')) {
throw new Exception("Invalid fraction bit string.");
}
}
}
}

/**
* The IEEE 754 fraction part for a float.
*/
public static class FloatFraction extends Part
{
/**
* Constructor.
* @param bits the string of character bits '0' and '1'
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public FloatFraction(String bits) throws Exception
{
super(FLOAT_FRACTION_SIZE, bits);
}
}

/**
* The IEEE 754 fraction part for a double.
*/
public static class DoubleFraction extends Part
{
/**
* Constructor.
* @param bits the string of character bits '0' and '1'
* @throws numbercruncher.mathutils.IEEE754.Exception
*/
public DoubleFraction(String bits) throws Exception
{
super(DOUBLE_FRACTION_SIZE, bits);
}
}
}
```

The class uses some of the conversion methods of the Integer, Long, Float, and Double wrapper classes. Methods Integer.parseInt() and Long.parseLong() parse a string representation of an integer value and a long value, respectively, in any base and return the value. Method Float.floatToIntBits() converts a float value to the int value that has the same bit representation. Similarly, method Double.doubleToLongBits() converts a double value to the long value that has the same bit representation. Methods Float.intBitsToFloat() and Double.longBitsToDouble() work the other way by converting an int value and a long value, respectively, to the float value and the double value that has the same bit representation.

The primary method of the class is decompose(). It takes a floating-point value that is represented as a character array of '0' s and '1' s and breaks the value into its various parts according to the standard.

The nested class Part and its subclasses FloatFraction and DoubleFraction support creating, validating, and manipulating the fraction parts of floating-point values.

Listing 3-1 shows Program 3-1, which uses class IEEE754 to decompose, reconstitute, and print the parts of various float and double values.

##### Listing 3-1 Using class IEEE754 to decompose, reconstitute, and print the parts of various float and double values.
```package numbercruncher.program3_1;

import numbercruncher.mathutils.IEEE754;
import numbercruncher.mathutils.IEEE754Constants;

/**
* PROGRAM 3-1: IEEE 754 Standard Floating-Point Formats
*
* Demonstrate the IEEE 754 standard floating-point formats
* with various float and double values.
*/
public class FPFormats implements IEEE754Constants
{
private void display() throws IEEE754.Exception
{
// Floats
float floats[] = {
-0.0f, 0.0f, -1.0f, 1.0f, 0.75f, -0.375f,
Float.MIN_VALUE, Float.MAX_VALUE,
Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY,
Float.NaN,
};
for (int i = 0; i < floats.length; ++i) {
new IEEE754(floats[i]).print();
}

// Doubles
double doubles[] = {
-0.375,
Double.MIN_VALUE, Double.MAX_VALUE,
Double.POSITIVE_INFINITY,
Double.NaN,
};
for (int i = 0; i < doubles.length; ++i) {
new IEEE754(doubles[i]).print();
}

System.out.println("C-----------------------------");

IEEE754 numbers[] = {

// Floats
new IEEE754(0,
IEEE754.toFloatBiasedExponent(-FLOAT_EXPONENT_BIAS),
new IEEE754.FloatFraction("00101")),
new IEEE754(0,
IEEE754.toFloatBiasedExponent(-126),
new IEEE754.FloatFraction("0")),
new IEEE754(0,
IEEE754.toFloatBiasedExponent(-FLOAT_EXPONENT_BIAS),
new IEEE754.FloatFraction("11111111111111111111111")),

// Doubles
new IEEE754(0,
IEEE754.toDoubleBiasedExponent(-DOUBLE_EXPONENT_BIAS),
new IEEE754.DoubleFraction("00101")),

new IEEE754(0,
IEEE754.toDoubleBiasedExponent(-1022),
new IEEE754.DoubleFraction("0")),
new IEEE754(0,
IEEE754.toDoubleBiasedExponent(-DOUBLE_EXPONENT_BIAS),
new IEEE754.DoubleFraction("11111111111111111111111111" +
"11111111111111111111111111")),
};

for (int i = 0; i < numbers.length; ++i) {
numbers[i].print();
}
}

/**
* Main.
* @param args the string array of program arguments
*/
public static void main(String args[])
{
FPFormats formats = new FPFormats();

try {
formats.display();
}

catch(IEEE754.Exception ex) {
System.out.println("***** Error: " + ex.getMessage());
}
}
}
```

Output:

```C-----------------------------
float value = -0.0
sign=1, exponent=00000000 (biased=0, zero)
significand=0.00000000000000000000000
C-----------------------------
float value = 0.0
sign=0, exponent=00000000 (biased=0, zero)
significand=0.00000000000000000000000
C-----------------------------
float value = -1.0
sign=1, exponent=01111111 (biased=127, normalized, unbiased=0)
significand=1.00000000000000000000000
C-----------------------------
float value = 1.0
sign=0, exponent=01111111 (biased=127, normalized, unbiased=0)
significand=1.00000000000000000000000
C-----------------------------
float value = 0.75
sign=0, exponent=01111110 (biased=126, normalized, unbiased=-1)
significand=1.10000000000000000000000
C-----------------------------
float value = -0.375
sign=1, exponent=01111101 (biased=125, normalized, unbiased=-2)
significand=1.10000000000000000000000
C-----------------------------
float value = 1.4E-45
sign=0, exponent=00000000 (biased=0, denormalized, use -126)
significand=0.00000000000000000000001
C-----------------------------
float value = 3.4028235E38
sign=0, exponent=11111110 (biased=254, normalized, unbiased=127)
significand=1.11111111111111111111111
C-----------------------------
float value = -Infinity
sign=1, exponent=11111111 (biased=255, reserved)
significand=0.00000000000000000000000
C-----------------------------
float value = Infinity
sign=0, exponent=11111111 (biased=255, reserved)
significand=0.00000000000000000000000
C-----------------------------
float value = NaN
sign=0, exponent=11111111 (biased=255, reserved)
significand=0.10000000000000000000000
C-----------------------------
double value = -0.375
sign=1, exponent=01111111101 (biased=1021, normalized, unbiased=-2)
significand=1.1000000000000000000000000000000000000000000000000000
C-----------------------------
double value = 4.9E-324
sign=0, exponent=00000000000 (biased=0, denormalized, use -1022)
significand=0.0000000000000000000000000000000000000000000000000001
C-----------------------------
double value = 1.7976931348623157E308
sign=0, exponent=11111111110 (biased=2046, normalized, unbiased=1023)
significand=1.1111111111111111111111111111111111111111111111111111
C-----------------------------
double value = Infinity
sign=0, exponent=11111111111 (biased=2047, reserved)
significand=0.0000000000000000000000000000000000000000000000000000
C-----------------------------
double value = NaN
sign=0, exponent=11111111111 (biased=2047, reserved)
significand=0.1000000000000000000000000000000000000000000000000000
C-----------------------------
C-----------------------------
float value = 1.83671E-39
sign=0, exponent=00000000 (biased=0, denormalized, use -126)
significand=0.00101000000000000000000
C-----------------------------
float value = 1.17549435E-38
sign=0, exponent=00000001 (biased=1, normalized, unbiased=-126)
significand=1.00000000000000000000000
C-----------------------------
float value = 1.1754942E-38
sign=0, exponent=00000000 (biased=0, denormalized, use -126)
significand=0.11111111111111111111111
C-----------------------------
double value = 3.4766779039175E-309
sign=0, exponent=00000000000 (biased=0, denormalized, use -1022)
significand=0.0010100000000000000000000000000000000000000000000000
C-----------------------------
double value = 2.2250738585072014E-308
sign=0, exponent=00000000001 (biased=1, normalized, unbiased=-1022)
significand=1.0000000000000000000000000000000000000000000000000000
C-----------------------------
double value = 2.225073858507201E-308
sign=0, exponent=00000000000 (biased=0, denormalized, use -1022)
significand=0.1111111111111111111111111111111111111111111111111111
```

Screen 3-1 is a screen shot of one of the interactive GUI-based versions of Program 3-1 in action. [2] There are two interactive versions a Java applet and a standalone program and they both also use class IEEE754. Because the interactive programs consist mostly of GUI code, we won't be looking at their source code. However, the Java source code for all the programs, interactive and noninteractive , can be downloaded. See the instructions in the preface.

[2] GUI = graphical user interface. For Java programs, that generally means an applet that runs inside of a Web browser window or a standalone application. Such programs usually use the Abstract Window Toolkit (AWT) classes or the more sophisticated Java Foundation Classes (JFC), also known as "Swing." To avoid running into the limitations of older Web browsers, the GUI programs in this book use only the AWT classes.

Each of the interactive programs comes in two versions, an applet version and a standalone version. You can download the Java source code for all the programs in this book. See the downloading instructions in the preface.

 Top