rossi.dfp
Class dfp

java.lang.Object
  |
  +--rossi.dfp.dfp
Direct Known Subclasses:
dfpdec

public class dfp
extends java.lang.Object

  Decimal floating point library for Java

  Another floating point class.  This one is built using radix 10000
  which is 10^4, so its almost decimal. 

  The design goals here are - 
     1.) decimal math, or close to it.  
     2.) Compile-time settable precision
     3.) Portability.  Code should be keep as portable as possible.
     4.) Performance
     5.) Accuracy  - Results should always be +/- 1 ULP for basic
         algebraic operation
     6.) Comply with IEEE 854-1987 as much as possible.
         (See IEEE 854-1987 notes below)

  The trade offs -
     1.) Memory foot print.  I'm using more memory than necessary to
         represent numbers to get better performance.  
     2.) Digits are bigger, so rounding is a greater loss.  So, if you
         really need 12 decimal digits, better use 4 base 10000 digits
         there can be one partially filled.

  Numbers are represented  in the following form:

  n  =  sign * mant * (radix) ^ exp;

  where sign is +/- 1, mantissa represents a fractional number between
  zero and one.  mant[0] is the least significant digit.
  exp is in the range of -32767 to 32768

  dfp objects are immuatable via their public interface.

  IEEE 854-1987  Notes and differences

  IEEE 854 requires the radix to be either 2 or 10.  The radix here is
  10000, so that requirement is not met, but  it is possible that a
  subclassed can be made to make it behave as a radix 10
  number.  It is my opinion that if it looks and behaves as a radix
  10 number then it is one and that requirement would be met.  
  
  The radix of 10000 was chosen because it should be faster to operate
  on 4 decimal digits at once intead of one at a time.  Radix 10 behaviour
  can be realized by add an additional rounding step to ensure that
  the number of decimal digits represented is constant.

  The IEEE standard specifically leaves out internal data encoding,
  so it is reasonable to conclude that such a subclass of this radix 
  10000 system is merely an encoding of a radix 10 system.

  IEEE 854 also specifies the existance of "sub-normal" numbers.  This
  class does not contain any such entities.  The most significant radix
  10000 digit is always non-zero.  Instead, we support "gradual underflow"
  by raising the underflow flag for numbers less with exponent less than
  expMin, but dont flush to zero until the exponent reaches expMin-DIGITS.
  Thus the smallest number we can represent would be:
  1E(-(minExp-DIGITS-1)*4),  eg, for DIGITS=5, minExp=-32767, that would
  be 1e-131092.

  IEEE 854 defines that the implied radix point lies just to the right
  of the most significant digit and to the left of the remaining digits.
  This implementation puts the implied radix point to the left of all
  digits including the most significant one.  The most significant digit
  here is the one just to the right of the radix point.  This is a fine
  detail and is really only a matter of definition.  Any side effects of
  this can be rendered invisible by a subclass.
  


Field Summary
static int DIGITS
          The number of digits.
static int errScale
          The amount under/overflows are scaled by before going to trap handler
protected  int exp
           
static byte FINITE
           
static int FLAG_DIV_ZERO
           
static int FLAG_INEXACT
           
static int FLAG_INVALID
           
static int FLAG_OVERFLOW
           
static int FLAG_UNDERFLOW
           
protected static int ieeeFlags
           
static byte INFINITE
           
protected  int[] mant
           
static int maxExp
          The maximum exponent before overflow is signaled and results flushed to infinity
static int minExp
          The minium exponent before underflow is signaled.
protected  byte nans
           
static dfp one
           
static byte QNAN
           
static int radix
          The radix, or base of this system.
protected static int rMode
           
static int ROUND_CEIL
          Rounds towards positive infinity
static int ROUND_DOWN
          Rounds toward zero.
static int ROUND_FLOOR
          Rounds towards negative infinity
static int ROUND_HALF_DOWN
          Rounds towards nearest unless both are equidistant in which case it rounds toward zero
static int ROUND_HALF_EVEN
          Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor.
static int ROUND_HALF_ODD
          Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor.
static int ROUND_HALF_UP
          Rounds towards nearest unless both are equidistant in which case it rounds away from zero
static int ROUND_UP
          Rounds away from zero if discarded digit is non-zero
protected  byte sign
           
static byte SNAN
           
static dfp two
           
static dfp zero
           
 
Constructor Summary
dfp()
          Default constructor.
dfp(dfp d)
          Copy constructor.
dfp(java.lang.String s)
          Create a dfp given a String representation
 
Method Summary
 dfp add(dfp x)
          Add x to this and return the result
protected  int align(int e)
          Make our exp equal to the supplied one.
 dfp ceil()
          Round to an integer using the ceil floor mode.
 int classify()
          Returns the type - one of FINITE, INFINITE, SNAN, QNAN
static void clearIEEEFlags()
          Clears the IEEE 854 status flags
protected static int compare(dfp a, dfp b)
          compare a and b.
protected  int complement(int extra)
          Negate the mantissa of this by computing the complement.
static dfp copysign(dfp x, dfp y)
          Creates a dfp that is the same as x except that it has the sign of y.
static dfp create(byte sign, byte nans)
          Creates a dfp with a non-finite value
protected  java.lang.String dfp2sci(dfp a)
           
protected  java.lang.String dfp2string(dfp a)
           
 dfp divide(dfp divisor)
          Divide this by divisor
 dfp divide(int divisor)
          Divide by a single digit less than radix.
 dfp dotrap(int type, java.lang.String what, dfp oper, dfp result)
          Raises a trap.
 boolean equal(dfp x)
          returns true if this is equal to x.
 dfp floor()
          Round to an integer using the round floor mode.
static int getIEEEFlags()
          Returns the IEEE 854 status flags
static int getRoundingMode()
          Returns the current rounding mode
 boolean greaterThan(dfp x)
          returns true if this is greater than x.
 int intValue()
          Convert this to an integer.
 boolean lessThan(dfp x)
          returns true if this is less than x.
 int log10()
          Return the exponent of the greatest power of 10 that is less than or equal to than abs(this).
 int log10K()
          Returns the exponent of the greatest power of 10000 that is less than or equal to the absolute value of this.
 dfp multiply(dfp x)
          Multiply this by x
 dfp multiply(int x)
          Multiply this by a single digit 0<=x<radix.
 dfp negate()
          Returns a number that is this number with the sign bit reversed
 dfp newInstance(dfp d)
          Create a dfp.
 dfp newInstance(java.lang.String s)
          Create a dfp.
 dfp nextAfter(dfp x)
          Returns the next number greater than this one in the direction of x.
 dfp power10(int e)
          Return the specified power of 10
 dfp power10K(int e)
          Return the specified power of 10000
 dfp remainder(dfp d)
          Returns the IEEE remainder.
 dfp rint()
          Round to nearest integer using the round-half-even method.
protected  int round(int n)
          round this given the next digit n using the current rounding mode returns a flag if an exception occured
static void setIEEEFlags(int flags)
          Sets the IEEE 854 status flags
static void setRoundingMode(int mode)
          Set the rounding mode to be one of the following values: ROUND_UP, ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_ODD, ROUND_CEIL, ROUND_FLOOR.
protected  void shiftLeft()
          Shift the mantissa left, and adjust the exponent to compensate
protected  void shiftRight()
          Shift the mantissa right, and adjust the exponent to compensate
 dfp sqrt()
           
protected  dfp string2dfp(java.lang.String fpin)
           
 dfp subtract(dfp a)
          Subtract a from this
 java.lang.String toString()
           
protected  dfp trap(int type, java.lang.String what, dfp oper, dfp def, dfp result)
          Trap handler.
protected  dfp trunc(int rmode)
          Does the integer conversions with the spec rounding.
 boolean unequal(dfp x)
          returns true if this is not equal to x.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

mant

protected int[] mant

sign

protected byte sign

exp

protected int exp

nans

protected byte nans

rMode

protected static int rMode

ieeeFlags

protected static int ieeeFlags

DIGITS

public static final int DIGITS
The number of digits. note these are radix 10000 digits, so each one is equivilent to 4 decimal digits

See Also:
Constant Field Values

radix

public static final int radix
The radix, or base of this system. Set to 10000

See Also:
Constant Field Values

minExp

public static final int minExp
The minium exponent before underflow is signaled. Flush to zero occurs at minExp-DIGITS

See Also:
Constant Field Values

maxExp

public static final int maxExp
The maximum exponent before overflow is signaled and results flushed to infinity

See Also:
Constant Field Values

errScale

public static final int errScale
The amount under/overflows are scaled by before going to trap handler

See Also:
Constant Field Values

ROUND_DOWN

public static final int ROUND_DOWN
Rounds toward zero. I.E. truncation

See Also:
Constant Field Values

ROUND_UP

public static final int ROUND_UP
Rounds away from zero if discarded digit is non-zero

See Also:
Constant Field Values

ROUND_HALF_UP

public static final int ROUND_HALF_UP
Rounds towards nearest unless both are equidistant in which case it rounds away from zero

See Also:
Constant Field Values

ROUND_HALF_DOWN

public static final int ROUND_HALF_DOWN
Rounds towards nearest unless both are equidistant in which case it rounds toward zero

See Also:
Constant Field Values

ROUND_HALF_EVEN

public static final int ROUND_HALF_EVEN
Rounds towards nearest unless both are equidistant in which case it rounds toward the even neighbor. This is the default as specified by IEEE 854-1987

See Also:
Constant Field Values

ROUND_HALF_ODD

public static final int ROUND_HALF_ODD
Rounds towards nearest unless both are equidistant in which case it rounds toward the odd neighbor.

See Also:
Constant Field Values

ROUND_CEIL

public static final int ROUND_CEIL
Rounds towards positive infinity

See Also:
Constant Field Values

ROUND_FLOOR

public static final int ROUND_FLOOR
Rounds towards negative infinity

See Also:
Constant Field Values

FINITE

public static final byte FINITE
See Also:
Constant Field Values

INFINITE

public static final byte INFINITE
See Also:
Constant Field Values

SNAN

public static final byte SNAN
See Also:
Constant Field Values

QNAN

public static final byte QNAN
See Also:
Constant Field Values

FLAG_INVALID

public static final int FLAG_INVALID
See Also:
Constant Field Values

FLAG_DIV_ZERO

public static final int FLAG_DIV_ZERO
See Also:
Constant Field Values

FLAG_OVERFLOW

public static final int FLAG_OVERFLOW
See Also:
Constant Field Values

FLAG_UNDERFLOW

public static final int FLAG_UNDERFLOW
See Also:
Constant Field Values

FLAG_INEXACT

public static final int FLAG_INEXACT
See Also:
Constant Field Values

zero

public static final dfp zero

one

public static final dfp one

two

public static final dfp two
Constructor Detail

dfp

public dfp()
Default constructor. Makes a dfp with a value of zero


dfp

public dfp(dfp d)
Copy constructor. Creates a copy of the supplied dfp


dfp

public dfp(java.lang.String s)
Create a dfp given a String representation

Method Detail

newInstance

public dfp newInstance(dfp d)
Create a dfp. Use this internally in preferenct to constructors to facilitate subclasses.


newInstance

public dfp newInstance(java.lang.String s)
Create a dfp. Use this internally in preferenct to constructors to facilitate subclasses.


shiftLeft

protected void shiftLeft()
Shift the mantissa left, and adjust the exponent to compensate


shiftRight

protected void shiftRight()
Shift the mantissa right, and adjust the exponent to compensate


align

protected int align(int e)
Make our exp equal to the supplied one. This may cause rounding. Also causes de-normalized numbers. These numbers are generally dangerous because most routines assume normalized numbers. Align doesn't round, so it will return the last digit destroyed by shifting right.


lessThan

public boolean lessThan(dfp x)
returns true if this is less than x. returns false if this or x is NaN


greaterThan

public boolean greaterThan(dfp x)
returns true if this is greater than x. returns false if this or x is NaN


equal

public boolean equal(dfp x)
returns true if this is equal to x. returns false if this or x is NaN


unequal

public boolean unequal(dfp x)
returns true if this is not equal to x. different from !equal(x) in the way NaNs are handled.


compare

protected static int compare(dfp a,
                             dfp b)
compare a and b. return -1 if ab and 0 if a==b Note this method does not properly handle NaNs.


rint

public dfp rint()
Round to nearest integer using the round-half-even method. That is round to nearest integer unless both are equidistant. In which case round to the even one.


floor

public dfp floor()
Round to an integer using the round floor mode. That is, round toward -Infinity


ceil

public dfp ceil()
Round to an integer using the ceil floor mode. That is, round toward +Infinity


remainder

public dfp remainder(dfp d)
Returns the IEEE remainder. That is the result of this less n times d, where n is the integer closest to this/d.


trunc

protected dfp trunc(int rmode)
Does the integer conversions with the spec rounding.


intValue

public int intValue()
Convert this to an integer. If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648.


log10K

public int log10K()
Returns the exponent of the greatest power of 10000 that is less than or equal to the absolute value of this. I.E. if this is 10e6 then log10K would return 1.


power10K

public dfp power10K(int e)
Return the specified power of 10000


log10

public int log10()
Return the exponent of the greatest power of 10 that is less than or equal to than abs(this).


power10

public dfp power10(int e)
Return the specified power of 10


complement

protected int complement(int extra)
Negate the mantissa of this by computing the complement. Leaves the sign bit unchanged, used internally by add. Denormalized numbers are handled properly here.


add

public dfp add(dfp x)
Add x to this and return the result


negate

public dfp negate()
Returns a number that is this number with the sign bit reversed


subtract

public dfp subtract(dfp a)
Subtract a from this


round

protected int round(int n)
round this given the next digit n using the current rounding mode returns a flag if an exception occured


multiply

public dfp multiply(dfp x)
Multiply this by x


multiply

public dfp multiply(int x)
Multiply this by a single digit 0<=x<radix. There are speed advantages in this special case


divide

public dfp divide(dfp divisor)
Divide this by divisor


divide

public dfp divide(int divisor)
Divide by a single digit less than radix. Special case, so there are speed advantages. 0 <= divisor < radix


sqrt

public dfp sqrt()

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

dfp2sci

protected java.lang.String dfp2sci(dfp a)

dfp2string

protected java.lang.String dfp2string(dfp a)

string2dfp

protected dfp string2dfp(java.lang.String fpin)

setRoundingMode

public static void setRoundingMode(int mode)
Set the rounding mode to be one of the following values: ROUND_UP, ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_ODD, ROUND_CEIL, ROUND_FLOOR. Default is ROUND_HALF_EVEN Note that the rounding mode is common to all instances in the system and will effect all future calculations.


getRoundingMode

public static int getRoundingMode()
Returns the current rounding mode


dotrap

public dfp dotrap(int type,
                  java.lang.String what,
                  dfp oper,
                  dfp result)
Raises a trap. This does not set the corresponding flag however.

Parameters:
type - the trap type
what - - name of routine trap occured in
oper - - input operator to function
result - - the result computed prior to the trap
Returns:
The suggested return value from the trap handler

trap

protected dfp trap(int type,
                   java.lang.String what,
                   dfp oper,
                   dfp def,
                   dfp result)
Trap handler. Subclasses may override this to provide trap functionality per IEEE 854-1987.

Parameters:
type - The exception type - e.g. FLAG_OVERFLOW
what - The name of the routine we were in e.g. divide()
oper - An operand to this function if any
def - The default return value if trap not enabled
result - The result that is spcefied to be delivered per IEEE 854, if any

getIEEEFlags

public static int getIEEEFlags()
Returns the IEEE 854 status flags


clearIEEEFlags

public static void clearIEEEFlags()
Clears the IEEE 854 status flags


setIEEEFlags

public static void setIEEEFlags(int flags)
Sets the IEEE 854 status flags


classify

public int classify()
Returns the type - one of FINITE, INFINITE, SNAN, QNAN


create

public static dfp create(byte sign,
                         byte nans)
Creates a dfp with a non-finite value


copysign

public static dfp copysign(dfp x,
                           dfp y)
Creates a dfp that is the same as x except that it has the sign of y. abs(x) = dfp.copysign(x, dfp.one)


nextAfter

public dfp nextAfter(dfp x)
Returns the next number greater than this one in the direction of x. If this==x then simply returns this.