KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > lang > math > DoubleRange


1 /*
2  * Copyright 2002-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.lang.math;
17
18 import java.io.Serializable JavaDoc;
19
20 /**
21  * <p><code>DoubleRange</code> represents an inclusive range of <code>double</code>s.</p>
22  *
23  * @author Stephen Colebourne
24  * @since 2.0
25  * @version $Id: DoubleRange.java 161243 2005-04-14 04:30:28Z ggregory $
26  */

27 public final class DoubleRange extends Range implements Serializable JavaDoc {
28     
29     private static final long serialVersionUID = 71849363892740L;
30
31     /**
32      * The minimum number in this range (inclusive).
33      */

34     private final double min;
35     /**
36      * The maximum number in this range (inclusive).
37      */

38     private final double max;
39     
40     /**
41      * Cached output minObject (class is immutable).
42      */

43     private transient Double JavaDoc minObject = null;
44     /**
45      * Cached output maxObject (class is immutable).
46      */

47     private transient Double JavaDoc maxObject = null;
48     /**
49      * Cached output hashCode (class is immutable).
50      */

51     private transient int hashCode = 0;
52     /**
53      * Cached output toString (class is immutable).
54      */

55     private transient String JavaDoc toString = null;
56     
57     /**
58      * <p>Constructs a new <code>DoubleRange</code> using the specified
59      * number as both the minimum and maximum in this range.</p>
60      *
61      * @param number the number to use for this range
62      * @throws IllegalArgumentException if the number is <code>NaN</code>
63      */

64     public DoubleRange(double number) {
65         super();
66         if (Double.isNaN(number)) {
67             throw new IllegalArgumentException JavaDoc("The number must not be NaN");
68         }
69         this.min = number;
70         this.max = number;
71     }
72
73     /**
74      * <p>Constructs a new <code>DoubleRange</code> using the specified
75      * number as both the minimum and maximum in this range.</p>
76      *
77      * @param number the number to use for this range, must not
78      * be <code>null</code>
79      * @throws IllegalArgumentException if the number is <code>null</code>
80      * @throws IllegalArgumentException if the number is <code>NaN</code>
81      */

82     public DoubleRange(Number JavaDoc number) {
83         super();
84         if (number == null) {
85             throw new IllegalArgumentException JavaDoc("The number must not be null");
86         }
87         this.min = number.doubleValue();
88         this.max = number.doubleValue();
89         if (Double.isNaN(min) || Double.isNaN(max)) {
90             throw new IllegalArgumentException JavaDoc("The number must not be NaN");
91         }
92         if (number instanceof Double JavaDoc) {
93             this.minObject = (Double JavaDoc) number;
94             this.maxObject = (Double JavaDoc) number;
95         }
96     }
97
98     /**
99      * <p>Constructs a new <code>DoubleRange</code> with the specified
100      * minimum and maximum numbers (both inclusive).</p>
101      *
102      * <p>The arguments may be passed in the order (min,max) or (max,min). The
103      * getMinimum and getMaximum methods will return the correct values.</p>
104      *
105      * @param number1 first number that defines the edge of the range, inclusive
106      * @param number2 second number that defines the edge of the range, inclusive
107      * @throws IllegalArgumentException if either number is <code>NaN</code>
108      */

109     public DoubleRange(double number1, double number2) {
110         super();
111         if (Double.isNaN(number1) || Double.isNaN(number2)) {
112             throw new IllegalArgumentException JavaDoc("The numbers must not be NaN");
113         }
114         if (number2 < number1) {
115             this.min = number2;
116             this.max = number1;
117         } else {
118             this.min = number1;
119             this.max = number2;
120         }
121     }
122
123     /**
124      * <p>Constructs a new <code>DoubleRange</code> with the specified
125      * minimum and maximum numbers (both inclusive).</p>
126      *
127      * <p>The arguments may be passed in the order (min,max) or (max,min). The
128      * getMinimum and getMaximum methods will return the correct values.</p>
129      *
130      * @param number1 first number that defines the edge of the range, inclusive
131      * @param number2 second number that defines the edge of the range, inclusive
132      * @throws IllegalArgumentException if either number is <code>null</code>
133      * @throws IllegalArgumentException if either number is <code>NaN</code>
134      */

135     public DoubleRange(Number JavaDoc number1, Number JavaDoc number2) {
136         super();
137         if (number1 == null || number2 == null) {
138             throw new IllegalArgumentException JavaDoc("The numbers must not be null");
139         }
140         double number1val = number1.doubleValue();
141         double number2val = number2.doubleValue();
142         if (Double.isNaN(number1val) || Double.isNaN(number2val)) {
143             throw new IllegalArgumentException JavaDoc("The numbers must not be NaN");
144         }
145         if (number2val < number1val) {
146             this.min = number2val;
147             this.max = number1val;
148             if (number2 instanceof Double JavaDoc) {
149                 this.minObject = (Double JavaDoc) number2;
150             }
151             if (number1 instanceof Double JavaDoc) {
152                 this.maxObject = (Double JavaDoc) number1;
153             }
154         } else {
155             this.min = number1val;
156             this.max = number2val;
157             if (number1 instanceof Double JavaDoc) {
158                 this.minObject = (Double JavaDoc) number1;
159             }
160             if (number2 instanceof Double JavaDoc) {
161                 this.maxObject = (Double JavaDoc) number2;
162             }
163         }
164     }
165
166     // Accessors
167
//--------------------------------------------------------------------
168

169     /**
170      * <p>Returns the minimum number in this range.</p>
171      *
172      * @return the minimum number in this range
173      */

174     public Number JavaDoc getMinimumNumber() {
175         if (minObject == null) {
176             minObject = new Double JavaDoc(min);
177         }
178         return minObject;
179     }
180
181     /**
182      * <p>Gets the minimum number in this range as a <code>long</code>.</p>
183      *
184      * <p>This conversion can lose information for large values or decimals.</p>
185      *
186      * @return the minimum number in this range
187      */

188     public long getMinimumLong() {
189         return (long) min;
190     }
191
192     /**
193      * <p>Gets the minimum number in this range as a <code>int</code>.</p>
194      *
195      * <p>This conversion can lose information for large values or decimals.</p>
196      *
197      * @return the minimum number in this range
198      */

199     public int getMinimumInteger() {
200         return (int) min;
201     }
202
203     /**
204      * <p>Gets the minimum number in this range as a <code>double</code>.</p>
205      *
206      * @return the minimum number in this range
207      */

208     public double getMinimumDouble() {
209         return min;
210     }
211
212     /**
213      * <p>Gets the minimum number in this range as a <code>float</code>.</p>
214      *
215      * <p>This conversion can lose information for large values.</p>
216      *
217      * @return the minimum number in this range
218      */

219     public float getMinimumFloat() {
220         return (float) min;
221     }
222
223     /**
224      * <p>Returns the maximum number in this range.</p>
225      *
226      * @return the maximum number in this range
227      */

228     public Number JavaDoc getMaximumNumber() {
229         if (maxObject == null) {
230             maxObject = new Double JavaDoc(max);
231         }
232         return maxObject;
233     }
234
235     /**
236      * <p>Gets the maximum number in this range as a <code>long</code>.</p>
237      *
238      * <p>This conversion can lose information for large values or decimals.</p>
239      *
240      * @return the maximum number in this range
241      */

242     public long getMaximumLong() {
243         return (long) max;
244     }
245
246     /**
247      * <p>Gets the maximum number in this range as a <code>int</code>.</p>
248      *
249      * <p>This conversion can lose information for large values or decimals.</p>
250      *
251      * @return the maximum number in this range
252      */

253     public int getMaximumInteger() {
254         return (int) max;
255     }
256
257     /**
258      * <p>Gets the maximum number in this range as a <code>double</code>.</p>
259      *
260      * @return the maximum number in this range
261      */

262     public double getMaximumDouble() {
263         return max;
264     }
265
266     /**
267      * <p>Gets the maximum number in this range as a <code>float</code>.</p>
268      *
269      * <p>This conversion can lose information for large values.</p>
270      *
271      * @return the maximum number in this range
272      */

273     public float getMaximumFloat() {
274         return (float) max;
275     }
276
277     // Tests
278
//--------------------------------------------------------------------
279

280     /**
281      * <p>Tests whether the specified <code>number</code> occurs within
282      * this range using <code>double</code> comparison.</p>
283      *
284      * <p><code>null</code> is handled and returns <code>false</code>.</p>
285      *
286      * @param number the number to test, may be <code>null</code>
287      * @return <code>true</code> if the specified number occurs within this range
288      */

289     public boolean containsNumber(Number JavaDoc number) {
290         if (number == null) {
291             return false;
292         }
293         return containsDouble(number.doubleValue());
294     }
295
296     /**
297      * <p>Tests whether the specified <code>double</code> occurs within
298      * this range using <code>double</code> comparison.</p>
299      *
300      * <p>This implementation overrides the superclass for performance as it is
301      * the most common case.</p>
302      *
303      * @param value the double to test
304      * @return <code>true</code> if the specified number occurs within this
305      * range by <code>double</code> comparison
306      */

307     public boolean containsDouble(double value) {
308         return value >= min && value <= max;
309     }
310
311     // Range tests
312
//--------------------------------------------------------------------
313

314     /**
315      * <p>Tests whether the specified range occurs entirely within this range
316      * using <code>double</code> comparison.</p>
317      *
318      * <p><code>null</code> is handled and returns <code>false</code>.</p>
319      *
320      * @param range the range to test, may be <code>null</code>
321      * @return <code>true</code> if the specified range occurs entirely within this range
322      * @throws IllegalArgumentException if the range is not of this type
323      */

324     public boolean containsRange(Range range) {
325         if (range == null) {
326             return false;
327         }
328         return containsDouble(range.getMinimumDouble())
329             && containsDouble(range.getMaximumDouble());
330     }
331
332     /**
333      * <p>Tests whether the specified range overlaps with this range
334      * using <code>double</code> comparison.</p>
335      *
336      * <p><code>null</code> is handled and returns <code>false</code>.</p>
337      *
338      * @param range the range to test, may be <code>null</code>
339      * @return <code>true</code> if the specified range overlaps with this range
340      */

341     public boolean overlapsRange(Range range) {
342         if (range == null) {
343             return false;
344         }
345         return range.containsDouble(min)
346             || range.containsDouble(max)
347             || containsDouble(range.getMinimumDouble());
348     }
349
350     // Basics
351
//--------------------------------------------------------------------
352

353     /**
354      * <p>Compares this range to another object to test if they are equal.</p>.
355      *
356      * <p>To be equal, the class, minimum and maximum must be equal.</p>
357      *
358      * @param obj the reference object with which to compare
359      * @return <code>true</code> if this object is equal
360      */

361     public boolean equals(Object JavaDoc obj) {
362         if (obj == this) {
363             return true;
364         }
365         if (obj instanceof DoubleRange == false) {
366             return false;
367         }
368         DoubleRange range = (DoubleRange) obj;
369         return (Double.doubleToLongBits(min) == Double.doubleToLongBits(range.min) &&
370                 Double.doubleToLongBits(max) == Double.doubleToLongBits(range.max));
371     }
372
373     /**
374      * <p>Gets a hashCode for the range.</p>
375      *
376      * @return a hash code value for this object
377      */

378     public int hashCode() {
379         if (hashCode == 0) {
380             hashCode = 17;
381             hashCode = 37 * hashCode + getClass().hashCode();
382             long lng = Double.doubleToLongBits(min);
383             hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32)));
384             lng = Double.doubleToLongBits(max);
385             hashCode = 37 * hashCode + ((int) (lng ^ (lng >> 32)));
386         }
387         return hashCode;
388     }
389
390     /**
391      * <p>Gets the range as a <code>String</code>.</p>
392      *
393      * <p>The format of the String is 'Range[<i>min</i>,<i>max</i>]'.</p>
394      *
395      * @return the <code>String</code> representation of this range
396      */

397     public String JavaDoc toString() {
398         if (toString == null) {
399             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(32);
400             buf.append("Range[");
401             buf.append(min);
402             buf.append(',');
403             buf.append(max);
404             buf.append(']');
405             toString = buf.toString();
406         }
407         return toString;
408     }
409
410 }
411
Popular Tags