KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > value > FloatValue


1 package net.sf.saxon.value;
2 import net.sf.saxon.Err;
3 import net.sf.saxon.ConversionContext;
4 import net.sf.saxon.expr.Token;
5 import net.sf.saxon.expr.XPathContext;
6 import net.sf.saxon.trans.DynamicError;
7 import net.sf.saxon.trans.XPathException;
8 import net.sf.saxon.type.BuiltInAtomicType;
9 import net.sf.saxon.type.ItemType;
10 import net.sf.saxon.type.Type;
11 import net.sf.saxon.type.ValidationException;
12
13 import java.math.BigDecimal JavaDoc;
14
15 /**
16 * A numeric (single precision floating point) value
17 */

18
19 public final class FloatValue extends NumericValue {
20     private float value;
21
22     /**
23      * Constructor supplying a string
24      */

25
26     public FloatValue(CharSequence JavaDoc val) throws DynamicError {
27         try {
28             this.value = (float)Value.stringToNumber(val);
29         } catch (NumberFormatException JavaDoc e) {
30             throw new DynamicError("Cannot convert string " + Err.wrap(val, Err.VALUE) + " to a float");
31         }
32     }
33
34     /**
35     * Constructor supplying a float
36     * @param value the value of the float
37     */

38
39     public FloatValue(float value) {
40         this.value = value;
41     }
42
43     /**
44     * Get the value
45     */

46
47     public float getValue() {
48         return value;
49     }
50
51     public double getDoubleValue() {
52         return (double)value;
53     }
54
55     /**
56      * Get the hashCode. This must conform to the rules for other NumericValue hashcodes
57      * @see NumericValue#hashCode
58      */

59
60     public int hashCode() {
61         if (value > Integer.MIN_VALUE && value < Integer.MAX_VALUE) {
62             return (int)value;
63         } else {
64             return new Double JavaDoc(this.getDoubleValue()).hashCode();
65         }
66     }
67
68     /**
69      * Test whether the value is the double/float value NaN
70      */

71
72     public boolean isNaN() {
73         return Float.isNaN(value);
74     }
75
76     /**
77      * Get the effective boolean value
78      * @param context
79      * @return true unless the value is zero or NaN
80      */

81     public boolean effectiveBooleanValue(XPathContext context) {
82         return (value!=0.0 && !Float.isNaN(value));
83     }
84
85     /**
86     * Convert to target data type
87     * @param requiredType an integer identifying the required atomic type
88     * @param conversion
89      * @return an AtomicValue, a value of the required type; or an ErrorValue
90     */

91
92     public AtomicValue convertPrimitive(BuiltInAtomicType requiredType, boolean validate, ConversionContext conversion) {
93         switch(requiredType.getPrimitiveType()) {
94         case Type.BOOLEAN:
95             return BooleanValue.get(value!=0.0 && !Float.isNaN(value));
96         case Type.FLOAT:
97         case Type.NUMBER:
98         case Type.ATOMIC:
99         case Type.ITEM:
100             return this;
101         case Type.INTEGER:
102             if (Float.isNaN(value)) {
103                 ValidationException err = new ValidationException("Cannot convert float NaN to an integer");
104                 err.setErrorCode("FORG0001");
105                 //err.setXPathContext(context);
106
return new ValidationErrorValue(err);
107             }
108             if (Float.isInfinite(value)) {
109                 ValidationException err = new ValidationException("Cannot convert float infinity to an integer");
110                 err.setErrorCode("FORG0001");
111                 //err.setXPathContext(context);
112
return new ValidationErrorValue(err);
113             }
114             if (value > Long.MAX_VALUE || value < Long.MIN_VALUE) {
115                 return new BigIntegerValue(new BigDecimal JavaDoc(value).toBigInteger());
116             }
117             return new IntegerValue((long)value);
118         case Type.DECIMAL:
119                 try {
120                     return new DecimalValue(value);
121                 } catch (ValidationException e) {
122                     return new ValidationErrorValue(e);
123                 }
124             case Type.DOUBLE:
125             return new DoubleValue((double)value);
126         case Type.STRING:
127             return new StringValue(getStringValueCS());
128         case Type.UNTYPED_ATOMIC:
129             return new UntypedAtomicValue(getStringValueCS());
130         default:
131             ValidationException err = new ValidationException("Cannot convert float to " +
132                                      requiredType.getDisplayName());
133             //err.setXPathContext(context);
134
err.setErrorCode("FORG0001");
135             return new ValidationErrorValue(err);
136         }
137     }
138
139
140     /**
141     * Get the value as a String
142     * @return a String representation of the value
143     */

144
145     public String JavaDoc getStringValue() {
146         return DoubleValue.doubleToString((double)value, Float.toString(value));
147     }
148
149     /**
150     * Determine the data type of the expression
151     * @return Type.DOUBLE
152     */

153
154     public ItemType getItemType() {
155         return Type.FLOAT_TYPE;
156     }
157
158     /**
159     * Negate the value
160     */

161
162     public NumericValue negate() {
163         return new FloatValue(-value);
164     }
165
166     /**
167     * Implement the XPath floor() function
168     */

169
170     public NumericValue floor() {
171         return new FloatValue((float)Math.floor(value));
172     }
173
174     /**
175     * Implement the XPath ceiling() function
176     */

177
178     public NumericValue ceiling() {
179         return new FloatValue((float)Math.ceil(value));
180     }
181
182     /**
183     * Implement the XPath round() function
184     */

185
186     public NumericValue round() {
187         if (Float.isNaN(value)) return this;
188         if (Float.isInfinite(value)) return this;
189         if (value==0.0) return this; // handles the negative zero case
190
if (value > -0.5 && value < 0.0) return new DoubleValue(-0.0);
191         if (value > Integer.MIN_VALUE && value < Integer.MAX_VALUE) {
192             return new FloatValue((float)Math.round(value));
193         }
194
195         // if the float is larger than the maximum int, then
196
// it can't have any significant digits after the decimal
197
// point, so return it unchanged
198

199         return this;
200     }
201
202     /**
203     * Implement the XPath round-to-half-even() function
204     */

205
206     public NumericValue roundToHalfEven(int scale) {
207         try {
208             return (FloatValue)new DoubleValue((double)value).roundToHalfEven(scale).convert(Type.FLOAT, null);
209         } catch (XPathException err) {
210             throw new AssertionError JavaDoc(err);
211         }
212     }
213
214     /**
215      * Determine whether the value is negative, zero, or positive
216      * @return -1 if negative, 0 if zero (including negative zero), +1 if positive, NaN if NaN
217      */

218
219     public double signum() {
220         if (Float.isNaN(value)) {
221             return value;
222         }
223         if (value > 0) return 1;
224         if (value == 0) return 0;
225         return -1;
226     }
227
228     /**
229     * Determine whether the value is a whole number, that is, whether it compares
230     * equal to some integer
231     */

232
233     public boolean isWholeNumber() {
234         return value == Math.floor(value) && !Float.isInfinite(value);
235     }
236
237     /**
238     * Evaluate a binary arithmetic operator.
239     */

240
241     public NumericValue arithmetic(int operator, NumericValue other, XPathContext context) throws XPathException {
242         if (other instanceof FloatValue) {
243             switch(operator) {
244                 case Token.PLUS:
245                     return new FloatValue(value + ((FloatValue)other).value);
246                 case Token.MINUS:
247                     return new FloatValue(value - ((FloatValue)other).value);
248                 case Token.MULT:
249                     return new FloatValue(value * ((FloatValue)other).value);
250                 case Token.DIV:
251                     return new FloatValue(value / ((FloatValue)other).value);
252                 case Token.IDIV:
253                     if (((FloatValue)other).value == 0.0) {
254                         DynamicError e = new DynamicError("Integer division by zero");
255                         e.setErrorCode("FOAR0001");
256                         e.setXPathContext(context);
257                         throw e;
258                     }
259                     return (NumericValue)(new FloatValue(value / ((FloatValue)other).value).convert(Type.INTEGER, context));
260                 case Token.MOD:
261                     return new FloatValue(value % ((FloatValue)other).value);
262                 default:
263                     throw new UnsupportedOperationException JavaDoc("Unknown operator");
264             }
265         } else if (other instanceof DoubleValue) {
266             return ((DoubleValue)convert(Type.DOUBLE, context)).arithmetic(operator, other, context);
267         } else {
268             return arithmetic(operator, (FloatValue)other.convert(Type.FLOAT, context), context);
269         }
270     }
271
272     /**
273      * Compare two values for equality. This supports identity constraints in XML Schema,
274      * which allow list-valued elements and attributes to participate in key and uniqueness constraints.
275      * This method returns false if any error occurs during the comparison, or if any of the items
276      * in either sequence is a node rather than an atomic value. The default implementation of
277      * schemaEquals() is the same as equals(), but subclasses can override this.
278      */

279
280     public boolean schemaEquals(Value obj) {
281         if (obj instanceof AtomicValue) {
282             obj = ((AtomicValue)obj).getPrimitiveValue();
283         }
284         if (obj instanceof FloatValue) {
285             return value == ((FloatValue)obj).value;
286         } else {
287             return false;
288         }
289     }
290
291     /**
292     * Convert to Java object (for passing to external functions)
293     */

294
295     public Object JavaDoc convertToJava(Class JavaDoc target, XPathContext context) throws XPathException {
296         if (target==Object JavaDoc.class) {
297             return new Double JavaDoc(value);
298         } else if (target.isAssignableFrom(DoubleValue.class)) {
299             return this;
300         } else if (target==boolean.class || target==Boolean JavaDoc.class) {
301             return Boolean.valueOf(value != 0.0 && !Float.isNaN(value));
302         } else if (target==String JavaDoc.class || target==CharSequence JavaDoc.class) {
303             return getStringValue();
304         } else if (target==double.class || target==Double JavaDoc.class) {
305             return new Double JavaDoc((double)value);
306         } else if (target==float.class ||target==Float JavaDoc.class ) {
307             return new Float JavaDoc(value);
308         } else if (target==long.class || target==Long JavaDoc.class) {
309             return new Long JavaDoc((long)value);
310         } else if (target==int.class || target==Integer JavaDoc.class) {
311             return new Integer JavaDoc((int)value);
312         } else if (target==short.class || target==Short JavaDoc.class) {
313             return new Short JavaDoc((short)value);
314         } else if (target==byte.class || target==Byte JavaDoc.class) {
315             return new Byte JavaDoc((byte)value);
316         } else if (target==char.class || target==Character JavaDoc.class) {
317             return new Character JavaDoc((char)value);
318         } else {
319             Object JavaDoc o = super.convertToJava(target, context);
320             if (o == null) {
321                 DynamicError err = new DynamicError("Conversion of float to " + target.getName() +
322                         " is not supported");
323                 err.setXPathContext(context);
324                 err.setErrorCode("SAXON:0000");
325             }
326             return o;
327         }
328     }
329
330 }
331
332 //
333
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
334
// you may not use this file except in compliance with the License. You may obtain a copy of the
335
// License at http://www.mozilla.org/MPL/
336
//
337
// Software distributed under the License is distributed on an "AS IS" basis,
338
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
339
// See the License for the specific language governing rights and limitations under the License.
340
//
341
// The Original Code is: all this file.
342
//
343
// The Initial Developer of the Original Code is Michael H. Kay.
344
//
345
// Contributor(s): none.
346
//
347

348
Popular Tags