Numeric.java 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright (c) 1997, 2009 Per M.A. Bothner.
  2. // This is free software; for terms and warranty disclaimer see ./COPYING.
  3. package gnu.math;
  4. import java.math.BigInteger;
  5. import java.math.BigDecimal;
  6. public abstract class Numeric extends java.lang.Number
  7. {
  8. public float floatValue () { return (float) doubleValue(); }
  9. public int intValue() { return (int) longValue(); }
  10. public long longValue() { return (long) doubleValue(); }
  11. /** Return this + k * obj. */
  12. public abstract Numeric add (Object obj, int k);
  13. public final Numeric add (Object obj) { return add (obj, 1); }
  14. public final Numeric sub (Object obj) { return add (obj, -1); }
  15. public abstract Numeric mul (Object obj);
  16. public abstract Numeric div (Object obj);
  17. public abstract Numeric abs ();
  18. public abstract Numeric neg ();
  19. public abstract String toString (int radix);
  20. public String toString () { return toString (10); }
  21. public static Numeric asNumericOrNull (Object value)
  22. {
  23. if (value instanceof Numeric)
  24. return (Numeric) value;
  25. if (value instanceof BigInteger || value instanceof Long
  26. || value instanceof Short || value instanceof Byte
  27. || value instanceof Integer || value instanceof UnsignedPrim)
  28. return IntNum.asIntNumOrNull(value);
  29. if (value instanceof BigDecimal)
  30. return RatNum.asRatNumOrNull(value);
  31. if (value instanceof Float || value instanceof Double)
  32. return new DFloNum(((Number) value).doubleValue());
  33. return null;
  34. }
  35. public abstract boolean isExact ();
  36. public Numeric toExact ()
  37. {
  38. return this;
  39. }
  40. public Numeric toInexact ()
  41. {
  42. return this;
  43. }
  44. public abstract boolean isZero ();
  45. /* Rounding modes: */
  46. public static final int FLOOR = 1;
  47. public static final int CEILING = 2;
  48. public static final int TRUNCATE = 3;
  49. public static final int ROUND = 4;
  50. /** Rounding mode to always produce a non-negative remainder.
  51. * Like FLOOR if the divisor is non-negative; CEILING otherwise.
  52. * Used to implement R6RS's div/mod operators.
  53. */
  54. public static final int NONNEG_MOD = 5;
  55. /** Return an integer for which of {@code this} or {@code obj} is larger.
  56. * Return 1 if {@code this>obj}; 0 if {@code this==obj};
  57. * -1 if {@code this<obj};
  58. * -2 if {@code this!=obj} otherwise (for example if either is NaN);
  59. * -3 if not comparable (incompatible types). */
  60. public int compare (Object obj)
  61. {
  62. return -3;
  63. }
  64. public int compareReversed (Numeric x)
  65. {
  66. throw new IllegalArgumentException ();
  67. }
  68. public boolean equals (Object obj)
  69. {
  70. if (obj == null || ! (obj instanceof Numeric))
  71. return false;
  72. return compare (obj) == 0;
  73. }
  74. public boolean grt (Object x)
  75. {
  76. return compare (x) > 0;
  77. }
  78. public boolean geq (Object x)
  79. {
  80. return compare (x) >= 0;
  81. }
  82. /** Calculate {@code x+k&this}. */
  83. public Numeric addReversed (Numeric x, int k)
  84. {
  85. throw new IllegalArgumentException ();
  86. }
  87. public Numeric mulReversed (Numeric x)
  88. {
  89. throw new IllegalArgumentException ();
  90. }
  91. public Numeric divReversed (Numeric x)
  92. {
  93. throw new IllegalArgumentException ();
  94. }
  95. /** Return the multiplicative inverse. */
  96. public Numeric div_inv ()
  97. {
  98. return IntNum.one().div(this);
  99. }
  100. /** Return the multiplicative identity. */
  101. public Numeric mul_ident ()
  102. {
  103. return IntNum.one();
  104. }
  105. /** Return this raised to an integer power.
  106. * Implemented by repeated squaring and multiplication.
  107. * If {@code y < 0}, returns div_inv of the result. */
  108. public Numeric power (IntNum y)
  109. {
  110. if (y.isNegative ())
  111. return power(IntNum.neg(y)).div_inv();
  112. Numeric pow2 = this;
  113. Numeric r = null;
  114. for (;;) // for (i = 0; ; i++)
  115. {
  116. // pow2 == x**(2**i)
  117. // prod = x**(sum(j=0..i-1, (y>>j)&1))
  118. if (y.isOdd())
  119. r = r == null ? pow2 : r.mul (pow2); // r *= pow2
  120. y = IntNum.shift (y, -1);
  121. if (y.isZero())
  122. break;
  123. // pow2 *= pow2;
  124. pow2 = pow2.mul (pow2);
  125. }
  126. return r == null ? mul_ident() : r;
  127. }
  128. }