KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > xquery > util > NumberValue


1 // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.xquery.util;
5 import gnu.math.*;
6 import gnu.mapping.*;
7 import java.math.BigDecimal JavaDoc;
8 import gnu.kawa.functions.Arithmetic;
9 import gnu.kawa.xml.*;
10 import gnu.xml.TextUtils;
11
12 public class NumberValue extends Procedure1
13 {
14   public static final NumberValue numberValue = new NumberValue();
15  
16   public static final Double JavaDoc NaN = new Double JavaDoc(Double.NaN);
17
18   public static boolean isNaN (Object JavaDoc arg)
19   {
20     return ((arg instanceof Double JavaDoc || arg instanceof Float JavaDoc
21              || arg instanceof DFloNum)
22             && Double.isNaN(((Number JavaDoc) arg).doubleValue()));
23   }
24
25   public Object JavaDoc apply1(Object JavaDoc arg)
26   {
27     if (arg != Values.empty && arg != null)
28       {
29         try
30           {
31             return numberValue(arg);
32           }
33         catch (Throwable JavaDoc ex)
34           {
35             // fall through to return NaN;
36
}
37       }
38     return NaN;
39   }
40
41   public static Number JavaDoc numberCast (Object JavaDoc value)
42   {
43     if (value == Values.empty || value == null)
44       return null;
45     if (value instanceof Values)
46       {
47         Values vals = (Values) value;
48         int ipos = vals.startPos();
49         int count = 0;
50         while ((ipos = vals.nextPos(ipos)) != 0)
51           {
52             if (count > 0)
53               throw new ClassCastException JavaDoc("non-singleton sequence cast to number");
54             value = vals.getPosPrevious(ipos);
55             count++;
56           }
57       }
58     if (value instanceof KNode || value instanceof UntypedAtomic)
59       return (Double JavaDoc) XDataType.doubleType.valueOf(TextUtils.stringValue(value));
60     return (Number JavaDoc) value;
61   }
62
63   public static Object JavaDoc numberValue (Object JavaDoc value)
64   {
65     value = KNode.atomicValue(value);
66     double d;
67     if (value instanceof UntypedAtomic || value instanceof String JavaDoc)
68       {
69         try
70           {
71             return XDataType.doubleType
72               .valueOf(TextUtils.stringValue(value));
73           }
74         catch (Throwable JavaDoc ex)
75           {
76             d = Double.NaN;
77           }
78       }
79     else if (value instanceof Number JavaDoc
80              && (value instanceof RealNum || ! (value instanceof Numeric)))
81       d = (((Number JavaDoc) value).doubleValue());
82     else
83       d = Double.NaN;
84     return XDataType.makeDouble(d);
85   }
86
87   public static Object JavaDoc abs (Object JavaDoc value)
88   {
89     if (value == null || value == Values.empty)
90       return value;
91     value = numberCast(value);
92     if (value instanceof Double JavaDoc)
93       {
94         Double JavaDoc d = (Double JavaDoc) value;
95         double x = d.doubleValue();
96         long bits = Double.doubleToRawLongBits(x);
97         if (bits >= 0)
98           return d;
99         bits &= 0x7fffffffffffffffL;
100         x = Double.longBitsToDouble(bits);
101         /* #ifdef JAVA5 */
102         // return Double.valueOf(x);
103
/* #else */
104         return new Double JavaDoc(x);
105         /* #endif */
106       }
107     if (value instanceof Float JavaDoc)
108       {
109         Float JavaDoc d = (Float JavaDoc) value;
110         float x = d.floatValue();
111         int bits = Float.floatToRawIntBits(x);
112         if (bits >= 0)
113           return d;
114         bits &= 0x7fffffff;
115         x = Float.intBitsToFloat(bits);
116         /* #ifdef JAVA5 */
117         // return Float.valueOf(x) ;
118
/* #else */
119         return new Float JavaDoc(x);
120         /* #endif */
121       }
122     if (value instanceof BigDecimal JavaDoc)
123       {
124         BigDecimal JavaDoc dec = (BigDecimal JavaDoc) value;
125         if (dec.signum() < 0)
126           dec = dec.negate();
127         return dec;
128       }
129     return ((Numeric) value).abs();
130   }
131
132   public static Object JavaDoc floor (Object JavaDoc val)
133   {
134     Number JavaDoc value = numberCast(val);
135     if (value == null)
136       return val;
137     if (value instanceof Double JavaDoc)
138       return XDataType.makeDouble(Math.floor(((Double JavaDoc) value).doubleValue()));
139     if (value instanceof Float JavaDoc)
140       return XDataType.makeFloat((float) Math.floor(((Float JavaDoc) value).floatValue()));
141     if (value instanceof BigDecimal JavaDoc)
142       {
143         BigDecimal JavaDoc dec = (BigDecimal JavaDoc) value;
144         return Arithmetic.asIntNum(dec.divide(XDataType.DECIMAL_ONE, 0, BigDecimal.ROUND_FLOOR).toBigInteger());
145       }
146     return ((RealNum) value).toInt(Numeric.FLOOR);
147   }
148
149   public static Object JavaDoc ceiling (Object JavaDoc val)
150   {
151     Number JavaDoc value = numberCast(val);
152     if (value == null)
153       return val;
154     if (value instanceof Double JavaDoc)
155       return XDataType.makeDouble(Math.ceil(((Double JavaDoc) value).doubleValue()));
156     if (value instanceof Float JavaDoc)
157       return XDataType.makeFloat((float) Math.ceil(((Float JavaDoc) value).floatValue()));
158     if (value instanceof BigDecimal JavaDoc)
159       {
160         BigDecimal JavaDoc dec = (BigDecimal JavaDoc) value;
161         return Arithmetic.asIntNum(dec.divide(XDataType.DECIMAL_ONE, 0, BigDecimal.ROUND_CEILING).toBigInteger());
162       }
163     return ((RealNum) value).toInt(Numeric.CEILING);
164   }
165
166   public static Object JavaDoc round (Object JavaDoc arg)
167   {
168     Number JavaDoc value = numberCast(arg);
169     if (value == null)
170       return arg;
171     if (value instanceof Double JavaDoc)
172       {
173         double val = ((Double JavaDoc) value).doubleValue();
174         if (val >= -0.5 && val <= 0.0
175             && (val < 0.0 || Double.doubleToLongBits(val) < 0))
176           val = -0.0;
177         else
178           val = Math.floor(val+0.5);
179         return XDataType.makeDouble(val);
180       }
181     if (value instanceof Float JavaDoc)
182       {
183         float val = ((Float JavaDoc) value).floatValue();
184         if (val >= -0.5 && val <= 0.0
185             && (val < 0.0 || Float.floatToIntBits(val) < 0))
186           val = (float) (-0.0);
187         else
188           val = (float) Math.floor(val+0.5);
189         return XDataType.makeFloat(val);
190       }
191     if (value instanceof BigDecimal JavaDoc)
192       {
193         BigDecimal JavaDoc dec = (BigDecimal JavaDoc) value;
194         int mode = dec.signum() >= 0 ? BigDecimal.ROUND_HALF_UP
195           : BigDecimal.ROUND_HALF_DOWN;
196         dec = dec.divide(XDataType.DECIMAL_ONE, 0, mode);
197         return Arithmetic.asIntNum(dec.toBigInteger());
198       }
199     return ((RealNum) value).toInt(Numeric.ROUND);
200   }
201
202   public static Object JavaDoc roundHalfToEven (Object JavaDoc value, IntNum precision)
203   {
204     Number JavaDoc number = numberCast(value);
205     if (number == null)
206       return value;
207     BigDecimal JavaDoc dec = (BigDecimal JavaDoc) XDataType.decimalType.cast(number);
208     int prec = precision.intValue();
209     /* #ifndef JAVA5 */
210     if (prec < 0)
211       {
212         BigDecimal JavaDoc power = null;
213         int shift = -prec;
214         if (shift >= 6)
215           {
216             BigDecimal JavaDoc million = BigDecimal.valueOf(1000000);
217             power = million;
218             while ((shift -= 6) >= 6)
219               power = power.multiply(million);
220           }
221         if (shift > 0)
222           {
223             int i = 10;
224             while (--shift > 0)
225               i = 10 * i;
226             BigDecimal JavaDoc tens = BigDecimal.valueOf(i);
227             power = power == null ? tens : power.multiply(tens);
228           }
229         dec = dec.divide(power, 0, BigDecimal.ROUND_HALF_EVEN);
230         dec = dec.multiply(power);
231       }
232     else
233     /* #endif */
234       dec = dec.setScale(prec, BigDecimal.ROUND_HALF_EVEN);
235     if (number instanceof Double JavaDoc)
236       return XDataType.makeDouble(dec.doubleValue());
237     if (number instanceof Float JavaDoc)
238       return XDataType.makeFloat(dec.floatValue());
239     if (number instanceof IntNum)
240       return XIntegerType.integerType.cast(dec);
241     return dec;
242   }
243
244   public static Object JavaDoc roundHalfToEven (Object JavaDoc value)
245   {
246     return roundHalfToEven(value, IntNum.zero());
247   }
248 }
249
Popular Tags