KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > functions > Arithmetic


1 /** Various utility methods and conversions for handling mixed-mode arithmetic.
2  * This should possibly be moved to gnu.math. */

3
4 package gnu.kawa.functions;
5 import gnu.math.*;
6 import java.math.*;
7
8 public class Arithmetic
9 {
10   /** Promotion code for byte/Byte, short/Short, int/Integer. */
11   public static final int INT_CODE = 1;
12   /** Promotion code for long/Long. */
13   public static final int LONG_CODE = 2;
14   /** Promotion code for java.math.BigInteger. */
15   public static final int BIGINTEGER_CODE = 3;
16   /** Promotion code for gnu.math.IntNum. */
17   public static final int INTNUM_CODE = 4;
18   /** Promotion code for java.math.BigDecimal. */
19   public static final int BIGDECIMAL_CODE = 5;
20   /** Promotion code for gnu.math.RatNum. */
21   public static final int RATNUM_CODE = 6;
22   /** Promotion code float/Float. */
23   public static final int FLOAT_CODE = 7;
24   /** Promotion code double/Double. */
25   public static final int DOUBLE_CODE = 8;
26   /** Promotion code for gnu.math.FloNum. */
27   public static final int FLONUM_CODE = 9;
28   /** Promotion code for other gnu.math.Numeric. */
29   public static final int NUMERIC_CODE = 10;
30
31   public static int classifyValue (Object JavaDoc value)
32   {
33     if (value instanceof Numeric)
34       {
35     if (value instanceof IntNum)
36       return INTNUM_CODE;
37     else if (value instanceof RatNum)
38       return RATNUM_CODE;
39     else if (value instanceof DFloNum)
40       return FLONUM_CODE;
41     else
42       return NUMERIC_CODE;
43       }
44     else if (value instanceof Number JavaDoc)
45       {
46     if (value instanceof Integer JavaDoc || value instanceof Short JavaDoc
47         || value instanceof Byte JavaDoc)
48       return INT_CODE;
49     else if (value instanceof Long JavaDoc)
50       return LONG_CODE;
51     else if (value instanceof Float JavaDoc)
52       return FLOAT_CODE;
53     else if (value instanceof Double JavaDoc)
54       return DOUBLE_CODE;
55     else if (value instanceof BigInteger)
56       return BIGINTEGER_CODE;
57     else if (value instanceof BigDecimal)
58       return BIGDECIMAL_CODE;
59     else
60       return -1;
61       }
62     else
63       return -1;
64   }
65
66   public static int asInt (Object JavaDoc value)
67   {
68     return ((Number JavaDoc) value).intValue();
69   }
70
71   public static long asLong (Object JavaDoc value)
72   {
73     return ((Number JavaDoc) value).longValue();
74   }
75
76   public static float asFloat (Object JavaDoc value)
77   {
78     return ((Number JavaDoc) value).floatValue();
79   }
80
81   public static double asDouble (Object JavaDoc value)
82   {
83     return ((Number JavaDoc) value).doubleValue();
84   }
85
86   public static BigInteger asBigInteger (Object JavaDoc value)
87   {
88     if (value instanceof BigInteger)
89       return (BigInteger) value;
90     if (value instanceof IntNum)
91       return new BigInteger(value.toString());
92     return BigInteger.valueOf(((Number JavaDoc) value).longValue());
93   }
94
95   public static IntNum asIntNum (BigDecimal value)
96   {
97     return IntNum.valueOf(((BigDecimal) value).toBigInteger().toString(), 10);
98   }
99
100   public static IntNum asIntNum (BigInteger value)
101   {
102     return IntNum.valueOf(value.toString(), 10);
103   }
104
105   public static IntNum asIntNum (Object JavaDoc value)
106   {
107     if (value instanceof IntNum)
108       return (IntNum) value;
109     if (value instanceof BigInteger)
110       return IntNum.valueOf(value.toString(), 10);
111     if (value instanceof BigDecimal)
112       return asIntNum((BigDecimal) value);
113     return IntNum.make(((Number JavaDoc) value).longValue());
114   }
115
116   public static BigDecimal asBigDecimal (Object JavaDoc value)
117   {
118     if (value instanceof BigDecimal)
119       return (BigDecimal) value;
120     if (value instanceof BigInteger)
121       return new BigDecimal((BigInteger) value);
122     if (value instanceof Long JavaDoc || value instanceof Integer JavaDoc
123     || value instanceof Short JavaDoc || value instanceof Byte JavaDoc)
124       return BigDecimal.valueOf(((Number JavaDoc) value).longValue());
125     return new BigDecimal(value.toString());
126   }
127
128   public static final IntNum ten_exp_9 = IntNum.make(1000000000);
129
130   public static RatNum asRatNum (Object JavaDoc value)
131   {
132     if (value instanceof RatNum)
133       return (RatNum) value;
134     if (value instanceof BigInteger)
135       return IntNum.valueOf(value.toString(), 10);
136     if (value instanceof BigDecimal)
137       {
138     BigDecimal d = (BigDecimal) value;
139     RatNum v = IntNum.valueOf(d.unscaledValue().toString(), 10);
140     int scale = d.scale();
141     for (; scale >= 9; scale -= 9)
142       v = RatNum.divide(v, ten_exp_9);
143     for (; scale <= -9; scale += 9)
144       v = RatNum.times(v, ten_exp_9);
145     IntNum scaleVal;
146     switch (scale > 0 ? scale : -scale)
147       {
148       case 1: scaleVal = IntNum.make(10); break;
149       case 2: scaleVal = IntNum.make(100); break;
150       case 3: scaleVal = IntNum.make(1000); break;
151       case 4: scaleVal = IntNum.make(10000); break;
152       case 5: scaleVal = IntNum.make(100000); break;
153       case 6: scaleVal = IntNum.make(1000000); break;
154       case 7: scaleVal = IntNum.make(10000000); break;
155       case 8: scaleVal = IntNum.make(100000000); break;
156       default:
157         return v;
158       }
159     if (scale > 0)
160       return RatNum.divide(v, scaleVal);
161     else
162       return RatNum.times(v, scaleVal);
163       }
164     else
165       return IntNum.make(((Number JavaDoc) value).longValue());
166   }
167
168   public static Numeric asNumeric (Object JavaDoc value)
169   {
170     if (! (value instanceof Numeric))
171       {
172     if (value instanceof BigInteger || value instanceof Long JavaDoc
173         || value instanceof Short JavaDoc || value instanceof Byte JavaDoc
174         || value instanceof Integer JavaDoc)
175       return asIntNum(value);
176     if (value instanceof BigDecimal)
177       return asRatNum(value);
178     if (value instanceof Float JavaDoc || value instanceof Double JavaDoc)
179       return new DFloNum(asDouble(value));
180       }
181     return (Numeric) value;
182   }
183
184   /** Convert a number to a String.
185    * Handles classes subclasses of gnu.math.Numeric
186    * as well as standard Java classes.
187    */

188   public static String JavaDoc toString (Object JavaDoc number, int radix)
189   {
190     int code = Arithmetic.classifyValue(number);
191     switch (code)
192       {
193       case Arithmetic.INT_CODE:
194         return Integer.toString(Arithmetic.asInt(number), radix);
195       case Arithmetic.LONG_CODE:
196         return Long.toString(Arithmetic.asLong(number), radix);
197       case Arithmetic.BIGINTEGER_CODE:
198         return Arithmetic.asBigInteger(number).toString(radix);
199       case Arithmetic.INTNUM_CODE:
200         return Arithmetic.asIntNum(number).toString(radix);
201       case Arithmetic.BIGDECIMAL_CODE:
202         if (radix == 10)
203           return Arithmetic.asBigDecimal(number).toString();
204         // else fall through:
205
case Arithmetic.FLOAT_CODE:
206         if (radix == 10)
207           return Float.toString(Arithmetic.asFloat(number));
208         // else fall through:
209
case Arithmetic.DOUBLE_CODE:
210       case Arithmetic.FLONUM_CODE:
211         if (radix == 10)
212           return Double.toString(Arithmetic.asDouble(number));
213         // else fall through:
214
case Arithmetic.RATNUM_CODE:
215       default:
216         return Arithmetic.asNumeric(number).toString(radix);
217       }
218   }
219
220   /** Coerce a number to one of the Arithmetic.XXX_CODE types.
221    * Assumes {@code > Arithmetic.classifyValue(value)}, though
222    * the converse might also work.
223    */

224   public static Object JavaDoc convert (Object JavaDoc value, int code)
225   {
226     switch (code)
227       {
228       case Arithmetic.INT_CODE:
229         if (value instanceof Integer JavaDoc)
230           return value;
231         int i = ((Number JavaDoc) value).intValue();
232         /* #ifdef JAVA5 */
233         // return Integer.valueOf(i);
234
/* #else */
235         return new Integer JavaDoc(i);
236         /* #endif */
237       case Arithmetic.LONG_CODE:
238         if (value instanceof Long JavaDoc)
239           return value;
240         long l = ((Number JavaDoc) value).longValue();
241         /* #ifdef JAVA5 */
242         // return Long.valueOf(l);
243
/* #else */
244         return new Long JavaDoc(l);
245         /* #endif */
246       case Arithmetic.BIGINTEGER_CODE:
247         return Arithmetic.asBigInteger(value);
248       case Arithmetic.INTNUM_CODE:
249         return Arithmetic.asIntNum(value);
250       case Arithmetic.BIGDECIMAL_CODE:
251         return Arithmetic.asBigDecimal(value);
252       case Arithmetic.RATNUM_CODE:
253         return Arithmetic.asRatNum(value);
254       case Arithmetic.FLOAT_CODE:
255         if (value instanceof Float JavaDoc)
256           return value;
257         float f = Arithmetic.asFloat(value);
258         /* #ifdef JAVA5 */
259         // return Float.valueOf(f);
260
/* #else */
261         return new Float JavaDoc(f);
262         /* #endif */
263       case Arithmetic.DOUBLE_CODE:
264         if (value instanceof Double JavaDoc)
265           return value;
266         double d = Arithmetic.asDouble(value);
267         /* #ifdef JAVA5 */
268         // return Double.valueOf(d);
269
/* #else */
270         return new Double JavaDoc(d);
271         /* #endif */
272       case Arithmetic.FLONUM_CODE:
273         if (value instanceof DFloNum)
274           return value;
275         return DFloNum.make(Arithmetic.asDouble(value));
276       default:
277         return (Number JavaDoc) value;
278       }
279   }
280 }
281
Popular Tags