001: // Copyright (c) 1997 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.math;
005:
006: public abstract class Numeric extends java.lang.Number {
007: public float floatValue() {
008: return (float) doubleValue();
009: }
010:
011: public int intValue() {
012: return (int) longValue();
013: }
014:
015: public long longValue() {
016: return (long) doubleValue();
017: }
018:
019: /** Return this + k * obj. */
020: public abstract Numeric add(Object obj, int k);
021:
022: public final Numeric add(Object obj) {
023: return add(obj, 1);
024: }
025:
026: public final Numeric sub(Object obj) {
027: return add(obj, -1);
028: }
029:
030: public abstract Numeric mul(Object obj);
031:
032: public abstract Numeric div(Object obj);
033:
034: public abstract Numeric abs();
035:
036: public abstract Numeric neg();
037:
038: public abstract String toString(int radix);
039:
040: public String toString() {
041: return toString(10);
042: }
043:
044: public abstract boolean isExact();
045:
046: public abstract boolean isZero();
047:
048: /* Rounding modes: */
049: public static final int FLOOR = 1;
050: public static final int CEILING = 2;
051: public static final int TRUNCATE = 3;
052: public static final int ROUND = 4;
053:
054: /** Return an integer for which of {# code this} or {#code obj} is larger.
055: * Return 1 if {@code this>obj}; 0 if {@code this==obj};
056: * -1 if {@code this<obj};
057: * -2 if {@code this!=obj} otherwise (for example if either is NaN);
058: * -3 if not comparable (incompatible types). */
059: public int compare(Object obj) {
060: return -3;
061: }
062:
063: public int compareReversed(Numeric x) {
064: throw new IllegalArgumentException();
065: }
066:
067: public boolean equals(Object obj) {
068: if (obj == null || !(obj instanceof Numeric))
069: return false;
070: return compare(obj) == 0;
071: }
072:
073: public boolean grt(Object x) {
074: return compare(x) > 0;
075: }
076:
077: public boolean geq(Object x) {
078: return compare(x) >= 0;
079: }
080:
081: /** Calculate x+k&this. */
082: public Numeric addReversed(Numeric x, int k) {
083: throw new IllegalArgumentException();
084: }
085:
086: public Numeric mulReversed(Numeric x) {
087: throw new IllegalArgumentException();
088: }
089:
090: public Numeric divReversed(Numeric x) {
091: throw new IllegalArgumentException();
092: }
093:
094: /** Return the multiplicative inverse. */
095: public Numeric div_inv() {
096: return IntNum.one().div(this );
097: }
098:
099: /** Return the multiplicative identity. */
100: public Numeric mul_ident() {
101: return IntNum.one();
102: }
103:
104: /** Return this raised to an integer power.
105: * Implemented by repeated squaring and multiplication.
106: * If y < 0, returns div_inv of the result. */
107: public Numeric power(IntNum y) {
108: if (y.isNegative())
109: return power(IntNum.neg(y)).div_inv();
110: Numeric pow2 = this ;
111: Numeric r = null;
112: for (;;) // for (i = 0; ; i++)
113: {
114: // pow2 == x**(2**i)
115: // prod = x**(sum(j=0..i-1, (y>>j)&1))
116: if (y.isOdd())
117: r = r == null ? pow2 : r.mul(pow2); // r *= pow2
118: y = IntNum.shift(y, -1);
119: if (y.isZero())
120: break;
121: // pow2 *= pow2;
122: pow2 = pow2.mul(pow2);
123: }
124: return r == null ? mul_ident() : r;
125: }
126:
127: }
|