|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Object | +--rossi.dfp.dfp
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 |
protected int[] mant
protected byte sign
protected int exp
protected byte nans
protected static int rMode
protected static int ieeeFlags
public static final int DIGITS
public static final int radix
public static final int minExp
public static final int maxExp
public static final int errScale
public static final int ROUND_DOWN
public static final int ROUND_UP
public static final int ROUND_HALF_UP
public static final int ROUND_HALF_DOWN
public static final int ROUND_HALF_EVEN
public static final int ROUND_HALF_ODD
public static final int ROUND_CEIL
public static final int ROUND_FLOOR
public static final byte FINITE
public static final byte INFINITE
public static final byte SNAN
public static final byte QNAN
public static final int FLAG_INVALID
public static final int FLAG_DIV_ZERO
public static final int FLAG_OVERFLOW
public static final int FLAG_UNDERFLOW
public static final int FLAG_INEXACT
public static final dfp zero
public static final dfp one
public static final dfp two
| Constructor Detail |
public dfp()
public dfp(dfp d)
public dfp(java.lang.String s)
| Method Detail |
public dfp newInstance(dfp d)
public dfp newInstance(java.lang.String s)
protected void shiftLeft()
protected void shiftRight()
protected int align(int e)
public boolean lessThan(dfp x)
public boolean greaterThan(dfp x)
public boolean equal(dfp x)
public boolean unequal(dfp x)
protected static int compare(dfp a,
dfp b)
public dfp rint()
public dfp floor()
public dfp ceil()
public dfp remainder(dfp d)
protected dfp trunc(int rmode)
public int intValue()
public int log10K()
public dfp power10K(int e)
public int log10()
public dfp power10(int e)
protected int complement(int extra)
public dfp add(dfp x)
public dfp negate()
public dfp subtract(dfp a)
protected int round(int n)
public dfp multiply(dfp x)
public dfp multiply(int x)
public dfp divide(dfp divisor)
public dfp divide(int divisor)
public dfp sqrt()
public java.lang.String toString()
toString in class java.lang.Objectprotected java.lang.String dfp2sci(dfp a)
protected java.lang.String dfp2string(dfp a)
protected dfp string2dfp(java.lang.String fpin)
public static void setRoundingMode(int mode)
public static int getRoundingMode()
public dfp dotrap(int type,
java.lang.String what,
dfp oper,
dfp result)
type - the trap typewhat - - name of routine trap occured inoper - - input operator to functionresult - - the result computed prior to the trap
protected dfp trap(int type,
java.lang.String what,
dfp oper,
dfp def,
dfp result)
type - The exception type - e.g. FLAG_OVERFLOWwhat - The name of the routine we were in e.g. divide()oper - An operand to this function if anydef - The default return value if trap not enabledresult - The result that is spcefied to be delivered per
IEEE 854, if anypublic static int getIEEEFlags()
public static void clearIEEEFlags()
public static void setIEEEFlags(int flags)
public int classify()
public static dfp create(byte sign,
byte nans)
public static dfp copysign(dfp x,
dfp y)
public dfp nextAfter(dfp x)
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||