Class Dfp
- java.lang.Object
-
- org.apache.commons.math.dfp.Dfp
-
- All Implemented Interfaces:
FieldElement<Dfp>
- Direct Known Subclasses:
DfpDec
public class Dfp extends java.lang.Object implements FieldElement<Dfp>
Decimal floating point library for JavaAnother floating point class. This one is built using radix 10000 which is 104, so its almost decimal.
The design goals here are:
- Decimal math, or close to it
- Settable precision (but no mix between numbers using different settings)
- Portability. Code should be keep as portable as possible.
- Performance
- Accuracy - Results should always be +/- 1 ULP for basic algebraic operation
- Comply with IEEE 854-1987 as much as possible. (See IEEE 854-1987 notes below)
Trade offs:
- Memory foot print. I'm using more memory than necessary to represent numbers to get better performance.
- 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 32768IEEE 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 instead of one at a time. Radix 10 behavior 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 existence 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 don't flush to zero until the exponent reaches MIN_EXP-digits. Thus the smallest number we can represent would be: 1E(-(MIN_EXP-digits-1)*4), eg, for digits=5, MIN_EXP=-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.
- Since:
- 2.2
- See Also:
DfpField
-
-
Field Summary
Fields Modifier and Type Field Description static int
ERR_SCALE
The amount under/overflows are scaled by before going to trap handlerstatic byte
FINITE
Indicator value for normal finite numbers.static byte
INFINITE
Indicator value for Infinity.static int
MAX_EXP
The maximum exponent before overflow is signaled and results flushed to infinitystatic int
MIN_EXP
The minimum exponent before underflow is signaled.static byte
QNAN
Indicator value for quiet NaN.static int
RADIX
The radix, or base of this system.static byte
SNAN
Indicator value for signaling NaN.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description Dfp
add(Dfp x)
Add x to this.Dfp
ceil()
Round to an integer using the round ceil mode.int
classify()
Returns the type - one of FINITE, INFINITE, SNAN, QNAN.static Dfp
copysign(Dfp x, Dfp y)
Creates an instance that is the same as x except that it has the sign of y.Dfp
divide(int divisor)
Divide by a single digit less than radix.Dfp
divide(Dfp divisor)
Divide this by divisor.Dfp
dotrap(int type, java.lang.String what, Dfp oper, Dfp result)
Raises a trap.boolean
equals(java.lang.Object other)
Check if instance is equal to x.Dfp
floor()
Round to an integer using the round floor mode.DfpField
getField()
Dfp
getOne()
Get the constant 1.int
getRadixDigits()
Get the number of radix digits of the instance.Dfp
getTwo()
Get the constant 2.Dfp
getZero()
Get the constant 0.boolean
greaterThan(Dfp x)
Check if instance is greater than x.int
hashCode()
Gets a hashCode for the instance.int
intValue()
Convert this to an integer.boolean
isInfinite()
Check if instance is infinite.boolean
isNaN()
Check if instance is not a number.boolean
lessThan(Dfp x)
Check if instance is less than x.int
log10()
Get the exponent of the greatest power of 10 that is less than or equal to abs(this).int
log10K()
Get the exponent of the greatest power of 10000 that is less than or equal to the absolute value of this.Dfp
multiply(int x)
Multiply this by a single digit 0<=x<radix.Dfp
multiply(Dfp x)
Multiply this by x.Dfp
negate()
Returns a number that is this number with the sign bit reversed.Dfp
newInstance()
Create an instance with a value of 0.Dfp
newInstance(byte x)
Create an instance from a byte value.Dfp
newInstance(byte sig, byte code)
Creates an instance with a non-finite value.Dfp
newInstance(double x)
Create an instance from a double value.Dfp
newInstance(int x)
Create an instance from an int value.Dfp
newInstance(long x)
Create an instance from a long value.Dfp
newInstance(java.lang.String s)
Create an instance from a String representation.Dfp
newInstance(Dfp d)
Create an instance by copying an existing one.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)
Get 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.Dfp
sqrt()
Compute the square root.Dfp
subtract(Dfp x)
Subtract x from this.double
toDouble()
Convert the instance into a double.double[]
toSplitDouble()
Convert the instance into a split double.java.lang.String
toString()
Get a string representation of the instance.boolean
unequal(Dfp x)
Check if instance is not equal to x.
-
-
-
Field Detail
-
RADIX
public static final int RADIX
The radix, or base of this system. Set to 10000- See Also:
- Constant Field Values
-
MIN_EXP
public static final int MIN_EXP
The minimum exponent before underflow is signaled. Flush to zero occurs at minExp-DIGITS- See Also:
- Constant Field Values
-
MAX_EXP
public static final int MAX_EXP
The maximum exponent before overflow is signaled and results flushed to infinity- See Also:
- Constant Field Values
-
ERR_SCALE
public static final int ERR_SCALE
The amount under/overflows are scaled by before going to trap handler- See Also:
- Constant Field Values
-
FINITE
public static final byte FINITE
Indicator value for normal finite numbers.- See Also:
- Constant Field Values
-
INFINITE
public static final byte INFINITE
Indicator value for Infinity.- See Also:
- Constant Field Values
-
SNAN
public static final byte SNAN
Indicator value for signaling NaN.- See Also:
- Constant Field Values
-
QNAN
public static final byte QNAN
Indicator value for quiet NaN.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
Dfp
public Dfp(Dfp d)
Copy constructor.- Parameters:
d
- instance to copy
-
-
Method Detail
-
newInstance
public Dfp newInstance()
Create an instance with a value of 0. Use this internally in preference to constructors to facilitate subclasses- Returns:
- a new instance with a value of 0
-
newInstance
public Dfp newInstance(byte x)
Create an instance from a byte value.- Parameters:
x
- value to convert to an instance- Returns:
- a new instance with value x
-
newInstance
public Dfp newInstance(int x)
Create an instance from an int value.- Parameters:
x
- value to convert to an instance- Returns:
- a new instance with value x
-
newInstance
public Dfp newInstance(long x)
Create an instance from a long value.- Parameters:
x
- value to convert to an instance- Returns:
- a new instance with value x
-
newInstance
public Dfp newInstance(double x)
Create an instance from a double value.- Parameters:
x
- value to convert to an instance- Returns:
- a new instance with value x
-
newInstance
public Dfp newInstance(Dfp d)
Create an instance by copying an existing one. Use this internally in preference to constructors to facilitate subclasses.- Parameters:
d
- instance to copy- Returns:
- a new instance with the same value as d
-
newInstance
public Dfp newInstance(java.lang.String s)
Create an instance from a String representation. Use this internally in preference to constructors to facilitate subclasses.- Parameters:
s
- string representation of the instance- Returns:
- a new instance parsed from specified string
-
newInstance
public Dfp newInstance(byte sig, byte code)
Creates an instance with a non-finite value.
-
getField
public DfpField getField()
Get theField
(really aDfpField
) to which the instance belongs.The field is linked to the number of digits and acts as a factory for
Dfp
instances.- Specified by:
getField
in interfaceFieldElement<Dfp>
- Returns:
Field
(really aDfpField
) to which the instance belongs
-
getRadixDigits
public int getRadixDigits()
Get the number of radix digits of the instance.- Returns:
- number of radix digits
-
getZero
public Dfp getZero()
Get the constant 0.- Returns:
- a Dfp with value zero
-
getOne
public Dfp getOne()
Get the constant 1.- Returns:
- a Dfp with value one
-
getTwo
public Dfp getTwo()
Get the constant 2.- Returns:
- a Dfp with value two
-
lessThan
public boolean lessThan(Dfp x)
Check if instance is less than x.- Parameters:
x
- number to check instance against- Returns:
- true if instance is less than x and neither are NaN, false otherwise
-
greaterThan
public boolean greaterThan(Dfp x)
Check if instance is greater than x.- Parameters:
x
- number to check instance against- Returns:
- true if instance is greater than x and neither are NaN, false otherwise
-
isInfinite
public boolean isInfinite()
Check if instance is infinite.- Returns:
- true if instance is infinite
-
isNaN
public boolean isNaN()
Check if instance is not a number.- Returns:
- true if instance is not a number
-
equals
public boolean equals(java.lang.Object other)
Check if instance is equal to x.- Overrides:
equals
in classjava.lang.Object
- Parameters:
other
- object to check instance against- Returns:
- true if instance is equal to x and neither are NaN, false otherwise
-
hashCode
public int hashCode()
Gets a hashCode for the instance.- Overrides:
hashCode
in classjava.lang.Object
- Returns:
- a hash code value for this object
-
unequal
public boolean unequal(Dfp x)
Check if instance is not equal to x.- Parameters:
x
- number to check instance against- Returns:
- true if instance is not equal to x and neither are NaN, false otherwise
-
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.- Returns:
- rounded value
-
floor
public Dfp floor()
Round to an integer using the round floor mode. That is, round toward -Infinity- Returns:
- rounded value
-
ceil
public Dfp ceil()
Round to an integer using the round ceil mode. That is, round toward +Infinity- Returns:
- rounded value
-
remainder
public Dfp remainder(Dfp d)
Returns the IEEE remainder.- Parameters:
d
- divisor- Returns:
- this less n × d, where n is the integer closest to this/d
-
intValue
public int intValue()
Convert this to an integer. If greater than 2147483647, it returns 2147483647. If less than -2147483648 it returns -2147483648.- Returns:
- converted number
-
log10K
public int log10K()
Get 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 106 then log10K would return 1.- Returns:
- integer base 10000 logarithm
-
power10K
public Dfp power10K(int e)
Get the specified power of 10000.- Parameters:
e
- desired power- Returns:
- 10000e
-
log10
public int log10()
Get the exponent of the greatest power of 10 that is less than or equal to abs(this).- Returns:
- integer base 10 logarithm
-
power10
public Dfp power10(int e)
Return the specified power of 10.- Parameters:
e
- desired power- Returns:
- 10e
-
add
public Dfp add(Dfp x)
Add x to this.- Specified by:
add
in interfaceFieldElement<Dfp>
- Parameters:
x
- number to add- Returns:
- sum of this and x
-
negate
public Dfp negate()
Returns a number that is this number with the sign bit reversed.- Returns:
- the opposite of this
-
subtract
public Dfp subtract(Dfp x)
Subtract x from this.- Specified by:
subtract
in interfaceFieldElement<Dfp>
- Parameters:
x
- number to subtract- Returns:
- difference of this and a
-
multiply
public Dfp multiply(Dfp x)
Multiply this by x.- Specified by:
multiply
in interfaceFieldElement<Dfp>
- Parameters:
x
- multiplicand- Returns:
- product of this and x
-
multiply
public Dfp multiply(int x)
Multiply this by a single digit 0<=x<radix. There are speed advantages in this special case- Parameters:
x
- multiplicand- Returns:
- product of this and x
-
divide
public Dfp divide(Dfp divisor)
Divide this by divisor.- Specified by:
divide
in interfaceFieldElement<Dfp>
- Parameters:
divisor
- divisor- Returns:
- quotient of 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- Parameters:
divisor
- divisor- Returns:
- quotient of this by divisor
-
sqrt
public Dfp sqrt()
Compute the square root.- Returns:
- square root of the instance
-
toString
public java.lang.String toString()
Get a string representation of the instance.- Overrides:
toString
in classjava.lang.Object
- Returns:
- string representation of the instance
-
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 typewhat
- - name of routine trap occurred inoper
- - input operator to functionresult
- - the result computed prior to the trap- Returns:
- The suggested return value from the trap handler
-
classify
public int classify()
Returns the type - one of FINITE, INFINITE, SNAN, QNAN.- Returns:
- type of the number
-
copysign
public static Dfp copysign(Dfp x, Dfp y)
Creates an instance that is the same as x except that it has the sign of y. abs(x) = dfp.copysign(x, dfp.one)- Parameters:
x
- number to get the value fromy
- number to get the sign from- Returns:
- a number with the value of x and the sign of y
-
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.- Parameters:
x
- direction where to look at- Returns:
- closest number next to instance in the direction of x
-
toDouble
public double toDouble()
Convert the instance into a double.- Returns:
- a double approximating the instance
- See Also:
toSplitDouble()
-
toSplitDouble
public double[] toSplitDouble()
Convert the instance into a split double.- Returns:
- an array of two doubles which sum represent the instance
- See Also:
toDouble()
-
-