ca.idms.io
Class FloatConverter

java.lang.Object
  extended by ca.idms.io.FloatConverter

public class FloatConverter
extends java.lang.Object

Converter class for IEEE BFP and IBM HFP. This class provides methods to convert between the Hexadecimal Floating Point (HFP) numbers traditionally used on IBM S/390 (and z900) systems and the IEEE Binary Floating Point (BFP) used in Java. The methods in this class are modeled (loosely) after the z900 CONVERT BFP TO HFP and CONVERT HFP TO BFP instructions. They support conversion of single and double precision numbers and a subset of the rounding methods used by the analagous z900 conversion instructions.

Single Precision Floating Point Representations

IEEE Binary Floating Point (BFP)

The format of the Java float type is 4 bytes, consisting of a sign bit, an 8 bit binary exponent in excess-127 notation, and a 23 bit binary mantissa (or fraction), arranged as:


 +---------------+---------------+---------------+---------------+
 |  s1,e7...e1   |  e0,m22...m16 |   m15...m8    |    m7...m0    |
 +---------------+---------------+---------------+---------------+

 where:

 s1       = sign bit
 e7...e0  = exponent bits
 m22...m0 = mantissa bits

 

The value of a normalized number is:

(-1)^(sign)*(1.mantissa)*(2^(exponent-127))

For a normalized number an implicit 1 is inserted in the fraction.

Example: 300.0 = 0x43960000

A denormalized (or subnormal) number can represent numbers whose magnitude is smaller than the lowest exponent (-126) at the cost of a loss of precision. Denormalized numbers have an exponent of all zeros and an explicit most significant bit in the mantissa.

Example: 1E-45 = 0x00000001

All bit patterns do not represent a numeric value. Non-numeric values include +/-Infinity and NaN (Not a Number) and have an exponent of all ones.

S/390 and z900 Hexadecimal Floating Point (HFP)

The format of the HFP float type is 4 bytes, consisting of a sign bit, a 7 bit hexadecimal exponent in excess-64 notation, and a 24 bit binary mantissa (or fraction), arranged as:


 +---------------+---------------+---------------+---------------+
 |  s1,e6...e0   |   m23...m16   |   m15...m8    |    m7...m0    |
 +---------------+---------------+---------------+---------------+

 where:

 s1       = sign bit
 e6...e0  = exponent bits
 m23...m0 = mantissa bits

 

The value of the number is

(-1^(sign)*(.mantissa)*(16^(exponent-64))

In a "normalized" number the first one to three bits may be zero. The most significant bit is explicit. Denormalized numbers are also supported. All bit patterns represent a numeric value.

Example: 300 = 4312C000

Double Precision Floating Point Representations

IEEE Binary Floating Point (BFP)

The format of the BFP double type is 8 bytes, consisting of a sign bit, an 11 bit binary exponent in excess-1023 notation, and a 52 bit binary mantissa, arranged as:


 +---------------+---------------+---------------+---------------+
 |  s1,e10...e4  |e3..e0,m51..m48|   m47...m40   |   m39...m32   |
 +---------------+---------------+---------------+---------------+
 |   m31...m24   |   m23...m16   |   m15...m8    |    m7...m0    |
 +---------------+---------------+---------------+---------------+

 where:

 s1       = sign bit
 e11...e0 = exponent bits
 m52...m0 = mantissa bits

 

The value of the number is

(-1)^(sign)*(1.mantissa)*(2^(exponent-1023))

For a normalized number an implicit 1 is inserted in the fraction.

Example: 300.0 = 0x4072C00000000000

A denormalized (or subnormal) number can represent numbers whose magnitude is smaller than the lowest exponent (-1022) at the cost of a loss of precision. Denormalized numbers have an exponent of all zeros and an explicit most significant bit in the mantissa.

Example: 4.9E-324 = 0x0000000000000001

All bit [atterns do not represent a numeric value. Non-numeric values include +/-Infinity and NaN (Not a Number) and have an exponent of all ones.

S/390 and z900 Hexadecimal Floating Point (HFP)

The format of the S/390 double type is 8 bytes, consisting of a sign bit, a 7 bit hexadecimal exponent in excess-64 notation, and a 56 bit binary mantissa, arranged as:


 +---------------+---------------+---------------+---------------+
 |  s1,e6...e0   |   m55...m48   |   m47...m40   |   m39...m32   |
 +---------------+---------------+---------------+---------------+
 |   m31...m24   |   m23...m16   |   m15...m8    |    m7...m0    |
 +---------------+---------------+---------------+---------------+

 where:

 s1       = sign bit
 e6...e0  = exponent bits
 m55...m0 = mantissa bits

 

The value of the number is

(-1^(sign)*(.mantissa)*(16^(exponent-64))

In a "normalized" number the first one to three bits may be zero. The most significant bit is explicit. Denormalized numbers are also supported. All bit patterns represent a numeric value.

Since:
CA IDMS Server 4.2 OS/390 Edition
Version:
2.00, 01/28/03
Author:
Dave Ross

Field Summary
static boolean DEF_NORM_HFP
          setNormalizeHFP(boolean) default.
static int DEF_ROUND_BFP
          setRoundBFP(int) default.
static int DEF_ROUND_HFP
          setRoundHFP(int) default.
static long HMAXD
          Largest (in magnitude) double precision HFP number.
static int HMAXF
          Largest (in magnitude) single precision HFP number.
static int ROUND_0
          Specifies "round toward 0".
static int ROUND_BIAS
          Specifies "biased round to nearest".
static int ROUND_NEAR
          Specifies "round to nearest".
static boolean trace
          Trace flag.
 
Constructor Summary
FloatConverter()
           
 
Method Summary
 long doubleToLongBits(double value)
          Converts a double precision IEEE BFP value to an S/390 or z900 HFP bit representation.
 int floatToIntBits(float value)
          Converts a single precision IEEE BFP value to an S/390 or z900 HFP bit representation.
 boolean getNormalizeHFP()
          Gets the BFP-->HFP normalization state.
 int getRoundBFP()
          Gets the HFP-->BFP rounding mode.
 int getRoundHFP()
          Gets the BFP-->HFP rounding mode.
 float intBitsToFloat(int bits)
          Converts a single precision S/390 or z900 HFP bit representation to an IEEE BFP value.
 double longBitsToDouble(long bits)
          Converts a double precision S/390 or z900 HFP bit representation to an IEEE BFP value.
 void setNormalizeHFP(boolean enable)
          Enables or disable BFP-->HFP normalization.
 void setRoundBFP(int mode)
          Sets the HFP-->BFP rounding mode.
 void setRoundHFP(int mode)
          Sets the BFP-->HFP rounding mode.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

HMAXF

public static final int HMAXF
Largest (in magnitude) single precision HFP number.

See Also:
Constant Field Values

HMAXD

public static final long HMAXD
Largest (in magnitude) double precision HFP number.

See Also:
Constant Field Values

ROUND_0

public static final int ROUND_0
Specifies "round toward 0". Discard all bits shifted out, equivalent to truncation.

See Also:
Constant Field Values

ROUND_BIAS

public static final int ROUND_BIAS
Specifies "biased round to nearest". Adds 1 to the bit to the last bit shifted out, propagates the carry, and discards all bits shifted out.

See Also:
Constant Field Values

ROUND_NEAR

public static final int ROUND_NEAR
Specifies "round to nearest". Adds 1 to the bit to the last bit shifted out, propagates the carry, and discards all bits shifted out. If the bits shifted out represented exactly one half, that is, 0x80000000, the last bit of the result is set to 0, the nearest even number.

See Also:
Constant Field Values

DEF_ROUND_BFP

public static int DEF_ROUND_BFP
setRoundBFP(int) default.


DEF_ROUND_HFP

public static int DEF_ROUND_HFP
setRoundHFP(int) default.


DEF_NORM_HFP

public static boolean DEF_NORM_HFP
setNormalizeHFP(boolean) default.


trace

public static boolean trace
Trace flag. This is meant for unit testing during development and is not currently integrated with the TraceObject trace. Output is to the System.out.

Constructor Detail

FloatConverter

public FloatConverter()
Method Detail

setRoundBFP

public void setRoundBFP(int mode)
Sets the HFP-->BFP rounding mode. The default is "round to nearest".

Parameters:
mode - rounding mode, ignored if invalid.
See Also:
ROUND_0, ROUND_BIAS, ROUND_NEAR, DEF_ROUND_BFP

getRoundBFP

public int getRoundBFP()
Gets the HFP-->BFP rounding mode.

Returns:
the current rounding mode
See Also:
setRoundBFP(int)

setRoundHFP

public void setRoundHFP(int mode)
Sets the BFP-->HFP rounding mode. The default is "round toward 0".

Parameters:
mode - rounding mode, ignored if invalid.
See Also:
ROUND_0, ROUND_BIAS, ROUND_NEAR, DEF_ROUND_HFP

getRoundHFP

public int getRoundHFP()
Gets the BFP-->HFP rounding mode.

Returns:
the current rounding mode
See Also:
setRoundBFP(int)

setNormalizeHFP

public void setNormalizeHFP(boolean enable)
Enables or disable BFP-->HFP normalization. When this is set to true, double precision BFP numbers that would result in unnormalized HFP numbers will be treated as underflow and converted to 0. This is consistent with the behavior of the CONVERT BFP TO HFP instruction. When set to false, the default, double precision BFP numbers that can be represented as unnormalized HFP numbers will be rounded and converted.

Parameters:
enable - true or false
See Also:
DEF_NORM_HFP, doubleToLongBits(double)

getNormalizeHFP

public boolean getNormalizeHFP()
Gets the BFP-->HFP normalization state.

Returns:
true if enabled, false otherwise.
See Also:
setNormalizeHFP(boolean)

floatToIntBits

public int floatToIntBits(float value)
Converts a single precision IEEE BFP value to an S/390 or z900 HFP bit representation. This method simulates the following z900 instructions:
      LE      R2,VALUE    load short BFP
      THDER   R0,R2       convert BFP to long HFP
      STE     R0,RESULT   return short HFP
 

The z900 Principles of Operation manual states that conversion from BFP to HFP is exact (and overflow and underflow cannot occur for short formats because of the difference in exponent width). This is because the z900 CONVERT BFP TO HFP instruction converts a short BFP to a long HFP, and thus does not need to round the result. Of course the application does need to deal with rounding to use a short format result. Using the left half of the target floating point register as a short HFP is equivalent to "round toward 0", or truncation. The z900 LOAD ROUNDED instruction is equivalent to "bias round to nearest". This method supports a subset of the z900 rounding modes to simulate either technique, with truncation as the default.

The following table describes how it handles the various special cases that occur when converting IEEE binary floating point (BFP) to z900 hexadecimal floating point (HFP). The rounding method is specified by setRoundHFP(int)

 BFP (a)                  HFP
 -Infinity <= a < -Hmax   -Hmax (1)
 -Hmax <= a <= -Hmin      rounded HFP
 -Hmin < a < 0            -0 (1)
 -0                       -0
 +0                       +0
 0 < a < +Hmin            +0 (1)
 +Hmin <= a <= +Hmax      rounded HFP
 +Hmax < a <= +Infinity   +Hmax (1)
 NaN                      +Hmax
 
Notes:
Hmax
Largest (in magnitude) number in HFP format
Hmin
Smallest (in magnitude) normalized inumber in HFP format
(1)
does not happen, short BFP always fits in short HFP

Parameters:
value - BFP number
Returns:
HFP bit represention

intBitsToFloat

public float intBitsToFloat(int bits)
Converts a single precision S/390 or z900 HFP bit representation to an IEEE BFP value. This method simulates the following z900 instructions:
      LZDR    R2          clear right half of register
      LE      R2,VALUE    load z900 short HFP, extended  to long
      TBEDR   R0,M3,R2    convert HFP to short BFP, M3 = rounding mode
      STE     R0,RESULT   return result
 
This method supports a subset of the explict rounding modes available for the S/390 CONVERT HFP TO BFP instruction.

The following table describes how it handles the various special cases that occur when converting S/390 hexadecimal floating point (HFP) to IEEE binary floating point (BFP). The rounding method is specified by setRoundBFP(int).

 HFP (a)                  BFP
 a < -Nmax                -Infinity (1)
 a < -Nmax                -Nmax (2)
 -Nmax <= a <= -Nmin      rounded BFP
 -Nmin < a <= -Dmin       denormalized BFP
 -Dmin < a < 0            denormalized BFP
 -0                       -0
 +0                       +0
 0 < a < +Dmin            denormalized BFP
 +Dmin <= a < +Nmin       denormalized BFP
 +Nmin <= a <= +Nmax      rounded BFP
 +Nmax < a                +Nmax (2)
 +Nmax < a                +Infinity (1)
 
Notes:
Dmin
Smallest (in magnitude) denormalized inumber in BFP format
Nmin
Smallest (in magnitude) normalized inumber in BFP format
Nmax
Largest (in magnitude) number in BFP format
(1)
with rounding method ROUND_BIAS or ROUND_NEAR
(2)
with rounding method ROUND_0

Parameters:
bits - S/390 HFP bit representation
Returns:
IEEE BFP number

doubleToLongBits

public long doubleToLongBits(double value)
Converts a double precision IEEE BFP value to an S/390 or z900 HFP bit representation. This method simulates the following z900 instructions:
      LD      R2,VALUE    load long BFP
      THDR    R0,R2       convert long BFP to long HFP
      STD     R0,RESULT   return long HFP
 
The z900 Principles of Operation manual states that conversion from BFP to HFP is exact (although overflow and underflow can occur for long formats because of the difference in exponent width). The CONVERT BFP TO HFP instruction always produces a normalized result, and by default this method works the same way. When the normalizeBFP option is disable, this method will use the effective rounding mode to attempt to return result for numbers that are smaller in magnitude than the smallest normalized representable HFP number, yet still representable as an unnormalized HFP number.

The following table describes how it handles the various special cases that occur when converting IEEE binary floating point (BFP) to S/390 hexadecimal floating point (HFP). The rounding method is specified by setRoundHFP(int). Normalization is enabled and disabled with setNormalizeHFP(boolean).

 BFP (a)                  HFP
 -Infinity <= a < -Hmax   -Hmax
 -Hmax <= a <= -Hmin      HFP
 -Hmin < a <= -Dmin       rounded HFP (1)
 -Hmin < a <= -Dmin       -0 (2)
 -Dmin < a < 0            -0
 -0                       -0
 +0                       +0
 0 < a < +Dmin            +0
 +Dmin <= a < +Hmin       +0 (2)
 +Dmin <= a < +Hmin       rounded HFP (1)
 +Hmin <= a <= +Hmax      HFP
 +Hmax < a <= +Infinity   +Hmax
 NaN                      +Hmax
 

Notes:

Dmin
Smallest (in magnitude) unnormalized inumber in HFP format
Hmax
Largest (in magnitude) number in HFP format
Hmin
Smallest (in magnitude) normalized inumber in HFP format
(1)
with "normalize HPF" disabled (the default)
(2)
with "normalize HPF" enabled

Parameters:
value - IEEE BFP number
Returns:
S/390 HFP bit represention
See Also:
setNormalizeHFP(boolean)

longBitsToDouble

public double longBitsToDouble(long bits)
Converts a double precision S/390 or z900 HFP bit representation to an IEEE BFP value. This method simulates the following z900 instructions:
      LD      R2,VALUE    load z900 long HFP
      TBDR    R0,M3,R2    convert HFP to BFP, M3 = rounding mode
      STD     R0,RESULT   return result
 
This method supports a subset of the explict rounding modes available for the S/390 CONVERT HFP TO BFP instruction.

The following table describes how it handles the various special cases that occur when converting S/390 hexadecimal floating point (HFP) to IEEE binary floating point (BFP). Since the BFP exponent is wider than the HFP exponent, there is no possibity of overflow or underflow when converting HFP to BFP. Since the BFP mantissa is narrower than the HFP mantissa, there is the possiblity of loss of precision when it is rounded to fit. The rounding method is specified by setRoundBFP(int). Since there are really no special cases, this table becomes trivial.

 HFP (a)                  BFP
 a < 0                    rounded BFP
 -0                       -0
 +0                       +0
 0 < a                    rounded BFP
 
Notes:
Dmin
Smallest (in magnitude) denormalized inumber in BFP format
Nmin
Smallest (in magnitude) normalized inumber in BFP format
Nmax
Largest (in magnitude) number in BFP format
(1)
rounding method ROUND_BIAS or ROUND_NEAR
(2)
rounding method ROUND_0

Parameters:
bits - S/390 HFP bit representation
Returns:
IEEE BFP number


Copyright © 2009 CA, All rights reserved