KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icl > saxon > expr > NumericValue


1 package com.icl.saxon.expr;
2 import com.icl.saxon.*;
3 import com.icl.saxon.functions.*;
4
5 import java.text.*;
6
7 /**
8 * A numeric (floating point) value
9 */

10
11 public final class NumericValue extends Value {
12     private double value;
13
14     /**
15     * Constructor supplying a double
16     * @value the value of the NumericValue
17     */

18
19     public NumericValue(double value) {
20         this.value = value;
21     }
22
23     /**
24     * Constructor supplying a String
25     * @s the numeric value expressed as a String
26     */

27
28     public NumericValue(String JavaDoc s) {
29         this.value = Value.stringToNumber(s);
30     }
31
32     /**
33     * Get the value as a String
34     * @return a String representation of the value
35     */

36
37     // Algorithm used up to 5.3.1
38

39     public String JavaDoc asStringOLD() {
40         if (Double.isNaN(value)) return "NaN";
41         if (Double.isInfinite(value)) return (value>0 ? "Infinity" : "-Infinity");
42         if (value==0.0) return "0";
43      
44         double absvalue = Math.abs(value);
45         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
46         if (value<0) sb.append('-');
47         int offset = (value<0 ? 1: 0);
48         double intpart = Math.floor(absvalue);
49         double fraction = absvalue - intpart;
50         if (intpart>=1) {
51             while (intpart>=1) {
52                 int nextdigit = (int)(intpart % 10);
53                 char digit = (char)(nextdigit + '0');
54                 sb.insert(offset, digit);
55                 intpart = Math.floor(intpart / 10);
56             }
57             
58         } else {
59             sb.append('0');
60         }
61         if (fraction > 0) {
62             sb.append('.');
63             while (fraction > 0) {
64                 double next = fraction * 10;
65                 if (next<1.000000000001 && next>0.999999999999) next=1.0;
66                 double nextdigit = Math.floor(next);
67                 char digit = (char)((int)nextdigit + '0');
68                 sb.append(digit);
69                 fraction = next % 1.0;
70             }
71         }
72         return sb.toString();
73     }
74
75     /**
76     * Get the value as a String
77     * @return a String representation of the value
78     */

79
80     // Code copied from James Clark's xt
81

82     public String JavaDoc asString() {
83         if (!Double.isInfinite(value)
84             && (value >= (double)(1L << 53)
85                     || -value >= (double)(1L << 53))) {
86             return new java.math.BigDecimal JavaDoc(value).toString();
87         }
88         String JavaDoc s = Double.toString(value);
89         int len = s.length();
90         if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0') {
91             s = s.substring(0, len - 2);
92             if (s.equals("-0"))
93                 return "0";
94             return s;
95         }
96         int e = s.indexOf('E');
97         if (e < 0)
98             return s;
99         int exp = Integer.parseInt(s.substring(e + 1));
100         String JavaDoc sign;
101         if (s.charAt(0) == '-') {
102             sign = "-";
103             s = s.substring(1);
104             --e;
105         }
106         else
107             sign = "";
108
109         int nDigits = e - 2;
110         if (exp >= nDigits) {
111             return sign + s.substring(0, 1) + s.substring(2, e) + zeros(exp - nDigits);
112         } else if (exp > 0) {
113             return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "." + s.substring(2 + exp, e);
114         } else {
115             // following line added at 6.5.3
116
while (s.charAt(e-1) == '0') e--;
117             return sign + "0." + zeros(-1 - exp) + s.substring(0, 1) + s.substring(2, e);
118         }
119     }
120     
121     static private String JavaDoc zeros(int n) {
122         char[] buf = new char[n];
123         for (int i = 0; i < n; i++)
124             buf[i] = '0';
125         return new String JavaDoc(buf);
126     }
127
128     /**
129     * Get the value as a number
130     * @return the numeric value
131     */

132
133     public double asNumber() {
134         return value;
135     }
136
137     /**
138     * Convert the value to a boolean
139     * @return false if zero, true otherwise
140     */

141
142     public boolean asBoolean() {
143         return (value!=0.0 && !Double.isNaN(value));
144     }
145
146     /**
147     * Determine the data type of the exprssion, if possible
148     * @return one of the values Value.STRING, Value.BOOLEAN, Value.NUMBER, Value.NODESET,
149     * Value.FRAGMENT, or Value.ANY (meaning not known in advance)
150     */

151
152     public int getDataType() {
153         return Value.NUMBER;
154     }
155
156
157     /**
158     * Get conversion preference for this value to a Java class. A low result
159     * indicates higher preference.
160     */

161        
162     public int conversionPreference(Class JavaDoc required) {
163
164         if (required==Object JavaDoc.class) return 17;
165         if (required.isAssignableFrom(NumericValue.class)) return 0;
166                 
167         if (required==boolean.class) return 14;
168         if (required==Boolean JavaDoc.class) return 15;
169         if (required==byte.class) return 12;
170         if (required==Byte JavaDoc.class) return 13;
171         if (required==char.class) return 10;
172         if (required==Character JavaDoc.class) return 11;
173         if (required==double.class) return 0;
174         if (required==Double JavaDoc.class) return 1;
175         if (required==float.class) return 2;
176         if (required==Float JavaDoc.class) return 3;
177         if (required==int.class) return 6;
178         if (required==Integer JavaDoc.class) return 7;
179         if (required==long.class) return 4;
180         if (required==Long JavaDoc.class) return 5;
181         if (required==short.class) return 8;
182         if (required==Short JavaDoc.class) return 9;
183         if (required==String JavaDoc.class) return 16;
184         return Integer.MAX_VALUE;
185     }
186
187     /**
188     * Convert to Java object (for passing to external functions)
189     */

190     
191     public Object JavaDoc convertToJava(Class JavaDoc target) throws XPathException {
192         if (target==Object JavaDoc.class) {
193             return new Double JavaDoc(value);
194         } else if (target.isAssignableFrom(NumericValue.class)) {
195             return this;
196         } else if (target==boolean.class) {
197             return new Boolean JavaDoc(asBoolean());
198         } else if (target==Boolean JavaDoc.class) {
199             return new Boolean JavaDoc(asBoolean());
200         } else if (target==String JavaDoc.class) {
201             return asString();
202         } else if (target==double.class) {
203             return new Double JavaDoc(value);
204         } else if (target==Double JavaDoc.class) {
205             return new Double JavaDoc(value);
206         } else if (target==float.class) {
207             return new Float JavaDoc(value);
208         } else if (target==Float JavaDoc.class) {
209             return new Float JavaDoc(value);
210         } else if (target==long.class) {
211             return new Long JavaDoc((long)value);
212         } else if (target==Long JavaDoc.class) {
213             return new Long JavaDoc((long)value);
214         } else if (target==int.class) {
215             return new Integer JavaDoc((int)value);
216         } else if (target==Integer JavaDoc.class) {
217             return new Integer JavaDoc((int)value);
218         } else if (target==short.class) {
219             return new Short JavaDoc((short)value);
220         } else if (target==Short JavaDoc.class) {
221             return new Short JavaDoc((short)value);
222         } else if (target==byte.class) {
223             return new Byte JavaDoc((byte)value);
224         } else if (target==Byte JavaDoc.class) {
225             return new Byte JavaDoc((byte)value);
226         } else if (target==char.class) {
227             return new Character JavaDoc((char)value);
228         } else if (target==Character JavaDoc.class) {
229             return new Character JavaDoc((char)value);
230         } else {
231             throw new XPathException("Conversion of number to " + target.getName() +
232                         " is not supported");
233         }
234     }
235
236     /**
237     * Diagnostic print of expression structure
238     */

239     
240     public void display(int level) {
241         System.err.println(indent(level) + "number (" + asString() + ")" );
242     }
243
244 }
245
246 //
247
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
248
// you may not use this file except in compliance with the License. You may obtain a copy of the
249
// License at http://www.mozilla.org/MPL/
250
//
251
// Software distributed under the License is distributed on an "AS IS" basis,
252
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
253
// See the License for the specific language governing rights and limitations under the License.
254
//
255
// The Original Code is: all this file except the asStringXT() and zeros() methods (not currently used).
256
//
257
// The Initial Developer of the Original Code is
258
// Michael Kay of International Computers Limited (mhkay@iclway.co.uk).
259
//
260
// Portions created by (xt) are Copyright (C) (James Clark). All Rights Reserved.
261
//
262
// Contributor(s): none.
263
//
264

265
Popular Tags