KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > types > ValueScaledInteger


1 package com.quadcap.sql.types;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.ByteArrayOutputStream JavaDoc;
42 import java.io.Externalizable JavaDoc;
43 import java.io.IOException JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.ObjectOutput JavaDoc;
46
47 import java.math.BigDecimal JavaDoc;
48 import java.math.BigInteger JavaDoc;
49
50 import com.quadcap.util.Debug;
51
52 /**
53  * A <b>BigDecimal</b> value.
54  *
55  * @author Stan Bailes
56  */

57 public class ValueScaledInteger extends Value implements Externalizable JavaDoc {
58     BigDecimal JavaDoc val;
59
60     public ValueScaledInteger() {}
61     
62     public ValueScaledInteger(BigDecimal JavaDoc val) {
63     this.val = val;
64     }
65
66     public ValueScaledInteger(String JavaDoc s) throws ValueException {
67     try {
68         this.val = new BigDecimal JavaDoc(s);
69         return;
70     } catch (NumberFormatException JavaDoc e) {
71     }
72
73     s = s.trim();
74     try {
75         this.val = new BigDecimal JavaDoc(s);
76         return;
77     } catch (NumberFormatException JavaDoc e) {
78     }
79     
80     int idx = s.indexOf('E');
81     if (idx < 0) idx = s.indexOf('e');
82     if (idx > 0) {
83         try {
84         this.val = new BigDecimal JavaDoc(s.substring(0, idx));
85         char c = s.charAt(idx+1);
86         int sign = 1;
87         if (c == '+') {
88             idx++;
89         } else if (c == '-') {
90             sign = -1;
91             idx++;
92         }
93         int exp = sign * Integer.parseInt(s.substring(idx+1));
94         val = val.movePointRight(exp);
95         return;
96         } catch (Throwable JavaDoc ee) {
97         }
98     }
99     throw new ValueException("DECIMAL format error: " + s);
100     }
101
102     public ValueScaledInteger(double v) throws ValueException {
103         try {
104             this.val = new BigDecimal JavaDoc(v);
105         } catch (Throwable JavaDoc t) {
106             throw new ValueException("Bad double value: " + v);
107         }
108                 
109     }
110
111     public ValueScaledInteger(long v) {
112     this.val = new BigDecimal JavaDoc(Long.toString(v));
113     }
114
115     public float floatValue() { return val.floatValue(); }
116     public double doubleValue() { return val.doubleValue(); }
117
118     public int requiredPrecision() {
119     String JavaDoc s = val.toString();
120     if (s.startsWith("-")) s = s.substring(1);
121     int idx = s.indexOf('.');
122     if (idx >= 0) {
123         s = s.substring(0, idx);
124     }
125     return s.length();
126     }
127
128     public void setScale(int s) {
129     val = val.setScale(s, BigDecimal.ROUND_HALF_DOWN);
130     }
131     
132     public Value binop(int op, Value l) throws ValueException {
133     return l.binop(op, this);
134     }
135
136     final Value binop(int op, long r) throws ValueException {
137     return ValueScaledInteger.binop(op, this, new ValueScaledInteger(r));
138     }
139
140     public Value binop(int op, ValueByte r) throws ValueException {
141     return binop(op, (long)r.byteValue());
142     }
143
144     public Value binop(int op, ValueShort r) throws ValueException {
145     return binop(op, (long)r.shortValue());
146     }
147
148     public Value binop(int op, ValueInteger r) throws ValueException {
149     return binop(op, (long)r.intValue());
150     }
151
152     public Value binop(int op, ValueLong r) throws ValueException {
153     return binop(op, r.longValue());
154     }
155
156     public Value binop(int op, ValueFloat r) throws ValueException {
157     return ValueDouble.binop(op, new ValueDouble(doubleValue()),
158                                  new ValueDouble(r.val));
159     }
160
161     public Value binop(int op, ValueDouble r) throws ValueException {
162     return ValueDouble.binop(op, new ValueDouble(doubleValue()), r);
163     }
164
165     public Value binop(int op, ValueNull r) throws ValueException {
166     switch (op) {
167     case Op.EQ:
168     case Op.NE:
169     case Op.LT:
170     case Op.LE:
171     case Op.GT:
172     case Op.GE:
173         return ValueUnknown.valueUnknown;
174     case Op.PLUS:
175     case Op.MINUS:
176     case Op.TIMES:
177     case Op.DIVIDE:
178     case Op.EXP:
179         return r;
180     case Op.COMPARE:
181         return r.valCmpNull();
182     default:
183         throw badBinop(op, r);
184     }
185     }
186
187     public Value binop(int op, ValueScaledInteger r) throws ValueException {
188     return ValueScaledInteger.binop(op, this, r);
189     }
190
191     public static final Value binop(int op, ValueScaledInteger e,
192                   ValueScaledInteger f)
193     throws ValueException
194     {
195     switch (op) {
196         case Op.DIVIDE:
197         try {
198                 //Debug.println("e = " + e.val + ", scale = " + e.val.scale());
199
//Debug.println("f = " + f.val + ", scale = " + f.val.scale());
200
//Debug.println("div = " + (e.val.divide(f.val,
201
// BigDecimal.ROUND_HALF_DOWN)));
202
return new
203             ValueScaledInteger(e.val.divide(f.val,
204                             BigDecimal.ROUND_HALF_DOWN));
205         } catch (ArithmeticException JavaDoc ae) {
206         throw new ValueException("divide by zero");
207         }
208         case Op.EQ:
209         return new ValueBoolean(0 == e.val.compareTo(f.val));
210         case Op.EXP:
211         return new
212         ValueScaledInteger(new BigDecimal JavaDoc(Math.pow(e.doubleValue(),
213                                f.doubleValue())));
214         case Op.GE:
215         return new ValueBoolean(0 <= e.val.compareTo(f.val));
216         case Op.GT:
217         return new ValueBoolean(0 < e.val.compareTo(f.val));
218         case Op.LE:
219         return new ValueBoolean(0 >= e.val.compareTo(f.val));
220         case Op.LT:
221         return new ValueBoolean(0 > e.val.compareTo(f.val));
222         case Op.MINUS:
223         return new ValueScaledInteger(e.val.subtract(f.val));
224         case Op.NE:
225         return new ValueBoolean(0 != e.val.compareTo(f.val));
226         case Op.PLUS:
227         return new ValueScaledInteger(e.val.add(f.val));
228         case Op.TIMES:
229         return new ValueScaledInteger(e.val.multiply(f.val));
230     case Op.COMPARE:
231         return new ValueInteger(e.val.compareTo(f.val));
232         
233     default:
234         throw badBinop(op, e, f);
235     }
236     }
237
238     public Value unop(int op) throws ValueException {
239     switch (op) {
240     case Op.NULL:
241         return new ValueBoolean(false);
242     case Op.PLUS:
243         return this;
244     case Op.MINUS:
245         BigDecimal JavaDoc zero = new BigDecimal JavaDoc(0);
246         return new ValueScaledInteger(zero.subtract(val));
247     default:
248         throw new ValueException("Unary op: " + Op.toString(op) +
249                      " not implemented for this type");
250     }
251     }
252     
253     public void readExternal(ObjectInput JavaDoc in)
254     throws IOException JavaDoc, ClassNotFoundException JavaDoc
255     {
256     val = (BigDecimal JavaDoc)in.readObject();
257     }
258     
259     public void writeExternal(ObjectOutput JavaDoc out)
260     throws IOException JavaDoc
261     {
262     out.writeObject(val);
263     }
264
265     final public BigDecimal JavaDoc bigDecimalValue() { return val; }
266     
267     public Object JavaDoc asJavaObject() {
268     return val;
269     }
270
271     public void fromJavaObject(Object JavaDoc obj) throws ValueException {
272     if (obj instanceof BigDecimal JavaDoc) {
273         val = (BigDecimal JavaDoc)obj;
274     } else {
275         throw new ValueException("bad type: " + obj);
276     }
277     }
278
279     public String JavaDoc toString() { return val.toString(); }
280
281     public Value convert(TypeTinyInt type) throws ValueException {
282         return TypeTinyInt.convertNumber(val.doubleValue());
283     }
284
285     public Value convert(TypeSmallInt type) throws ValueException {
286         return TypeSmallInt.convertNumber(val.doubleValue());
287     }
288
289     public Value convert(TypeInt type) throws ValueException {
290         return TypeInt.convertNumber(val.doubleValue());
291     }
292
293     public Value convert(TypeBigInt type) throws ValueException {
294         return TypeBigInt.convertNumber(val.doubleValue());
295     }
296
297     public Value convert(TypeDecimal type) throws ValueException {
298         if (type.getPrecision() > 0) {
299             double lim =
300                 Math.pow(10, type.getPrecision() - type.getScale());
301             if (doubleValue() >= lim || doubleValue() <= (0-lim)) {
302                 throw new ValueException("Value out of range: " + this);
303             }
304         }
305         if (val.scale() == type.getScale() || type.getScale() == -1) {
306             return this;
307         } else {
308             return new ValueScaledInteger(val.setScale(type.getScale(),
309                                                        BigDecimal.ROUND_HALF_DOWN));
310         }
311     }
312
313     public Value convert(TypeReal type) throws ValueException {
314     if (type.getMaxPrecision() > 31) {
315         return new ValueDouble(val.doubleValue());
316     } else {
317         return new ValueFloat(val.floatValue());
318     }
319     }
320
321     public Type getType() {
322     return new TypeDecimal(requiredPrecision(), val.scale());
323     }
324
325     public void serializeKey(KeyStream out) throws IOException JavaDoc {
326     out.writeLength(2, KeyStream.COMPOUND);
327     BigInteger JavaDoc bi = val.toBigInteger();
328     out.writeInt(bi.toByteArray());
329     BigDecimal JavaDoc frac = val.subtract(new BigDecimal JavaDoc(bi));
330     ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
331     String JavaDoc f = frac.toString();
332     int accum = 0;
333     for (int i = 0; i < f.length(); i++) {
334         accum <<= 4;
335         accum |= f.charAt(i) - '0';
336         if ((i % 2) == 1) bos.write(accum);
337         accum = 0;
338     }
339     if ((f.length() % 2) == 1) bos.write(accum);
340     out.write(bos.toByteArray());
341     }
342 }
343
Popular Tags