Source Code Cross Referenced for MathUtils.java in  » Template-Engine » Velocity » org » apache » velocity » runtime » parser » node » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Template Engine » Velocity » org.apache.velocity.runtime.parser.node 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.apache.velocity.runtime.parser.node;
002:
003:        /*
004:         * Licensed to the Apache Software Foundation (ASF) under one
005:         * or more contributor license agreements.  See the NOTICE file
006:         * distributed with this work for additional information
007:         * regarding copyright ownership.  The ASF licenses this file
008:         * to you under the Apache License, Version 2.0 (the
009:         * "License"); you may not use this file except in compliance
010:         * with the License.  You may obtain a copy of the License at
011:         *
012:         *   http://www.apache.org/licenses/LICENSE-2.0
013:         *
014:         * Unless required by applicable law or agreed to in writing,
015:         * software distributed under the License is distributed on an
016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017:         * KIND, either express or implied.  See the License for the
018:         * specific language governing permissions and limitations
019:         * under the License.    
020:         */
021:
022:        import java.math.BigDecimal;
023:        import java.math.BigInteger;
024:        import java.util.HashMap;
025:        import java.util.Map;
026:        import java.util.List;
027:        import java.util.ArrayList;
028:
029:        /**
030:         * Utility-class for all arithmetic-operations.<br><br>
031:         *
032:         * All operations (+ - / *) return a Number which type is the type of the bigger argument.<br>
033:         * Example:<br>
034:         * <code>add ( new Integer(10), new Integer(1))</code> will return an <code>Integer</code>-Object with the value 11<br>
035:         * <code>add ( new Long(10), new Integer(1))</code> will return an <code>Long</code>-Object with the value 11<br>
036:         * <code>add ( new Integer(10), new Float(1))</code> will return an <code>Float</code>-Object with the value 11<br><br>
037:         *
038:         * Overflow checking:<br>
039:         * For integral values (byte, short, int) there is an implicit overflow correction (the next "bigger"
040:         * type will be returned). For example, if you call <code>add (new Integer (Integer.MAX_VALUE), 1)</code> a
041:         * <code>Long</code>-object will be returned with the correct value of <code>Integer.MAX_VALUE+1</code>.<br>
042:         * In addition to that the methods <code>multiply</code>,<code>add</code> and <code>substract</code> implement overflow
043:         * checks for <code>long</code>-values. That means that if an overflow occurs while working with long values a BigInteger
044:         * will be returned.<br>
045:         * For all other operations and types (such as Float and Double) there is no overflow checking.
046:         *
047:         * @author <a href="mailto:pero@antaramusic.de">Peter Romianowski</a>
048:         */
049:
050:        public abstract class MathUtils {
051:
052:            /**
053:             * A BigDecimal representing the number 0
054:             */
055:            protected static final BigDecimal DECIMAL_ZERO = new BigDecimal(
056:                    BigInteger.ZERO);
057:
058:            /**
059:             * The constants are used to determine in which context we have to calculate.
060:             */
061:            protected static final int BASE_LONG = 0;
062:            protected static final int BASE_FLOAT = 1;
063:            protected static final int BASE_DOUBLE = 2;
064:            protected static final int BASE_BIGINTEGER = 3;
065:            protected static final int BASE_BIGDECIMAL = 4;
066:
067:            /**
068:             * The <code>Class</code>-object is key, the maximum-value is the value
069:             */
070:            protected static final Map ints = new HashMap();
071:            static {
072:                ints.put(Byte.class, BigDecimal.valueOf(Byte.MAX_VALUE));
073:                ints.put(Short.class, BigDecimal.valueOf(Short.MAX_VALUE));
074:                ints.put(Integer.class, BigDecimal.valueOf(Integer.MAX_VALUE));
075:                ints.put(Long.class, BigDecimal.valueOf(Long.MAX_VALUE));
076:                ints.put(BigInteger.class, BigDecimal.valueOf(-1));
077:            }
078:
079:            /**
080:             * The "size" of the number-types - ascending.
081:             */
082:            protected static final List typesBySize = new ArrayList();
083:            static {
084:                typesBySize.add(Byte.class);
085:                typesBySize.add(Short.class);
086:                typesBySize.add(Integer.class);
087:                typesBySize.add(Long.class);
088:                typesBySize.add(Float.class);
089:                typesBySize.add(Double.class);
090:            }
091:
092:            /**
093:             * Convert the given Number to a BigDecimal
094:             * @param n
095:             * @return The number as BigDecimal
096:             */
097:            public static BigDecimal toBigDecimal(Number n) {
098:
099:                if (n instanceof  BigDecimal) {
100:                    return (BigDecimal) n;
101:                }
102:
103:                if (n instanceof  BigInteger) {
104:                    return new BigDecimal((BigInteger) n);
105:                }
106:
107:                return new BigDecimal(n.doubleValue());
108:
109:            }
110:
111:            /**
112:             * Convert the given Number to a BigInteger
113:             * @param n
114:             * @return The number as BigInteger
115:             */
116:            public static BigInteger toBigInteger(Number n) {
117:
118:                if (n instanceof  BigInteger) {
119:                    return (BigInteger) n;
120:                }
121:
122:                return BigInteger.valueOf(n.longValue());
123:
124:            }
125:
126:            /**
127:             * Compare the given Number to 0.
128:             * @param n
129:             * @return True if number is 0.
130:             */
131:            public static boolean isZero(Number n) {
132:                if (isInteger(n)) {
133:                    if (n instanceof  BigInteger) {
134:                        return ((BigInteger) n).compareTo(BigInteger.ZERO) == 0;
135:                    }
136:                    return n.doubleValue() == 0;
137:                }
138:                if (n instanceof  Float) {
139:                    return n.floatValue() == 0f;
140:                }
141:                if (n instanceof  Double) {
142:                    return n.doubleValue() == 0d;
143:                }
144:                return toBigDecimal(n).compareTo(DECIMAL_ZERO) == 0;
145:            }
146:
147:            /**
148:             * Test, whether the given object is an integer value
149:             * (Byte, Short, Integer, Long, BigInteger)
150:             * @param n
151:             * @return True if n is an integer.
152:             */
153:            public static boolean isInteger(Number n) {
154:                return ints.containsKey(n.getClass());
155:            }
156:
157:            /**
158:             * Wrap the given primitive into the given class if the value is in the
159:             * range of the destination type. If not the next bigger type will be chosen.
160:             * @param value
161:             * @param type
162:             * @return Number object representing the primitive.
163:             */
164:            public static Number wrapPrimitive(long value, Class type) {
165:                if (type == Byte.class) {
166:                    if (value > Byte.MAX_VALUE || value < Byte.MIN_VALUE) {
167:                        type = Short.class;
168:                    } else {
169:                        // TODO: JDK 1.4+ -> valueOf()
170:                        return new Byte((byte) value);
171:                    }
172:                }
173:                if (type == Short.class) {
174:                    if (value > Short.MAX_VALUE || value < Short.MIN_VALUE) {
175:                        type = Integer.class;
176:                    } else {
177:                        // TODO: JDK 1.4+ -> valueOf()
178:                        return new Short((short) value);
179:                    }
180:                }
181:                if (type == Integer.class) {
182:                    if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
183:                        type = Long.class;
184:                    } else {
185:                        // TODO: JDK 1.4+ -> valueOf()
186:                        return new Integer((int) value);
187:                    }
188:                }
189:                if (type == Long.class) {
190:                    // TODO: JDK 1.4+ -> valueOf()
191:                    return new Long(value);
192:                }
193:                return BigInteger.valueOf(value);
194:            }
195:
196:            /**
197:             * Wrap the result in the object of the bigger type.
198:             * 
199:             * @param value result of operation (as a long) - used to check size
200:             * @param op1 first operand of binary operation
201:             * @param op2 second operand of binary operation
202:             * @return Number object of appropriate size to fit the value and operators
203:             */
204:            private static Number wrapPrimitive(long value, Number op1,
205:                    Number op2) {
206:                if (typesBySize.indexOf(op1.getClass()) > typesBySize
207:                        .indexOf(op2.getClass())) {
208:                    return wrapPrimitive(value, op1.getClass());
209:                }
210:                return wrapPrimitive(value, op2.getClass());
211:            }
212:
213:            /**
214:             * Find the common Number-type to be used in calculations.
215:             * 
216:             * @param op1 first operand of binary operation
217:             * @param op2 second operand of binary operation
218:             * @return constant indicating type of Number to use in calculations
219:             */
220:            private static int findCalculationBase(Number op1, Number op2) {
221:
222:                boolean op1Int = isInteger(op1);
223:                boolean op2Int = isInteger(op2);
224:
225:                if ((op1 instanceof  BigDecimal || op2 instanceof  BigDecimal)
226:                        || ((!op1Int || !op2Int) && (op1 instanceof  BigInteger || op2 instanceof  BigInteger))) {
227:                    return BASE_BIGDECIMAL;
228:                }
229:
230:                if (op1Int && op2Int) {
231:                    if (op1 instanceof  BigInteger || op2 instanceof  BigInteger) {
232:                        return BASE_BIGINTEGER;
233:                    }
234:                    return BASE_LONG;
235:                }
236:
237:                if ((op1 instanceof  Double) || (op2 instanceof  Double)) {
238:                    return BASE_DOUBLE;
239:                }
240:                return BASE_FLOAT;
241:            }
242:
243:            /**
244:             * Add two numbers and return the correct value / type.
245:             * Overflow detection is done for integer values (byte, short, int, long) only!
246:             * @param op1
247:             * @param op2
248:             * @return Addition result.
249:             */
250:            public static Number add(Number op1, Number op2) {
251:
252:                int calcBase = findCalculationBase(op1, op2);
253:                switch (calcBase) {
254:                case BASE_BIGINTEGER:
255:                    return toBigInteger(op1).add(toBigInteger(op2));
256:                case BASE_LONG:
257:                    long l1 = op1.longValue();
258:                    long l2 = op2.longValue();
259:                    long result = l1 + l2;
260:
261:                    // Overflow check
262:                    if ((result ^ l1) < 0 && (result ^ l2) < 0) {
263:                        return toBigInteger(op1).add(toBigInteger(op2));
264:                    }
265:                    return wrapPrimitive(result, op1, op2);
266:                case BASE_FLOAT:
267:                    return new Float(op1.floatValue() + op2.floatValue());
268:                case BASE_DOUBLE:
269:                    return new Double(op1.doubleValue() + op2.doubleValue());
270:
271:                    // Default is BigDecimal operation
272:                default:
273:                    return toBigDecimal(op1).add(toBigDecimal(op2));
274:                }
275:            }
276:
277:            /**
278:             * Subtract two numbers and return the correct value / type.
279:             * Overflow detection is done for integer values (byte, short, int, long) only!
280:             * @param op1
281:             * @param op2
282:             * @return Subtraction result.
283:             */
284:            public static Number subtract(Number op1, Number op2) {
285:
286:                int calcBase = findCalculationBase(op1, op2);
287:                switch (calcBase) {
288:                case BASE_BIGINTEGER:
289:                    return toBigInteger(op1).subtract(toBigInteger(op2));
290:                case BASE_LONG:
291:                    long l1 = op1.longValue();
292:                    long l2 = op2.longValue();
293:                    long result = l1 - l2;
294:
295:                    // Overflow check
296:                    if ((result ^ l1) < 0 && (result ^ ~l2) < 0) {
297:                        return toBigInteger(op1).subtract(toBigInteger(op2));
298:                    }
299:                    return wrapPrimitive(result, op1, op2);
300:                case BASE_FLOAT:
301:                    return new Float(op1.floatValue() - op2.floatValue());
302:                case BASE_DOUBLE:
303:                    return new Double(op1.doubleValue() - op2.doubleValue());
304:
305:                    // Default is BigDecimal operation
306:                default:
307:                    return toBigDecimal(op1).subtract(toBigDecimal(op2));
308:                }
309:            }
310:
311:            /**
312:             * Multiply two numbers and return the correct value / type.
313:             * Overflow detection is done for integer values (byte, short, int, long) only!
314:             * @param op1
315:             * @param op2
316:             * @return Multiplication result.
317:             */
318:            public static Number multiply(Number op1, Number op2) {
319:
320:                int calcBase = findCalculationBase(op1, op2);
321:                switch (calcBase) {
322:                case BASE_BIGINTEGER:
323:                    return toBigInteger(op1).multiply(toBigInteger(op2));
324:                case BASE_LONG:
325:                    long l1 = op1.longValue();
326:                    long l2 = op2.longValue();
327:                    long result = l1 * l2;
328:
329:                    // Overflow detection
330:                    if ((l2 != 0) && (result / l2 != l1)) {
331:                        return toBigInteger(op1).multiply(toBigInteger(op2));
332:                    }
333:                    return wrapPrimitive(result, op1, op2);
334:                case BASE_FLOAT:
335:                    return new Float(op1.floatValue() * op2.floatValue());
336:                case BASE_DOUBLE:
337:                    return new Double(op1.doubleValue() * op2.doubleValue());
338:
339:                    // Default is BigDecimal operation
340:                default:
341:                    return toBigDecimal(op1).multiply(toBigDecimal(op2));
342:                }
343:            }
344:
345:            /**
346:             * Divide two numbers. The result will be returned as Integer-type if and only if
347:             * both sides of the division operator are Integer-types. Otherwise a Float, Double,
348:             * or BigDecimal will be returned.
349:             * @param op1
350:             * @param op2
351:             * @return Division result.
352:             */
353:            public static Number divide(Number op1, Number op2) {
354:
355:                int calcBase = findCalculationBase(op1, op2);
356:                switch (calcBase) {
357:                case BASE_BIGINTEGER:
358:                    BigInteger b1 = toBigInteger(op1);
359:                    BigInteger b2 = toBigInteger(op2);
360:                    return b1.divide(b2);
361:
362:                case BASE_LONG:
363:                    long l1 = op1.longValue();
364:                    long l2 = op2.longValue();
365:                    return wrapPrimitive(l1 / l2, op1, op2);
366:
367:                case BASE_FLOAT:
368:                    return new Float(op1.floatValue() / op2.floatValue());
369:                case BASE_DOUBLE:
370:                    return new Double(op1.doubleValue() / op2.doubleValue());
371:
372:                    // Default is BigDecimal operation
373:                default:
374:                    return toBigDecimal(op1).divide(toBigDecimal(op2),
375:                            BigDecimal.ROUND_HALF_DOWN);
376:                }
377:            }
378:
379:            /**
380:             * Modulo two numbers.
381:             * @param op1
382:             * @param op2
383:             * @return Modulo result.
384:             *
385:             * @throws ArithmeticException If at least one parameter is a BigDecimal
386:             */
387:            public static Number modulo(Number op1, Number op2)
388:                    throws ArithmeticException {
389:
390:                int calcBase = findCalculationBase(op1, op2);
391:                switch (calcBase) {
392:                case BASE_BIGINTEGER:
393:                    return toBigInteger(op1).mod(toBigInteger(op2));
394:                case BASE_LONG:
395:                    return wrapPrimitive(op1.longValue() % op2.longValue(),
396:                            op1, op2);
397:                case BASE_FLOAT:
398:                    return new Float(op1.floatValue() % op2.floatValue());
399:                case BASE_DOUBLE:
400:                    return new Double(op1.doubleValue() % op2.doubleValue());
401:
402:                    // Default is BigDecimal operation
403:                default:
404:                    throw new ArithmeticException(
405:                            "Cannot calculate the modulo of BigDecimals.");
406:                }
407:            }
408:
409:            /**
410:             * Compare two numbers.
411:             * @param op1
412:             * @param op2
413:             * @return 1 if n1 > n2, -1 if n1 < n2 and 0 if equal.
414:             */
415:            public static int compare(Number op1, Number op2) {
416:
417:                int calcBase = findCalculationBase(op1, op2);
418:                switch (calcBase) {
419:                case BASE_BIGINTEGER:
420:                    return toBigInteger(op1).compareTo(toBigInteger(op2));
421:                case BASE_LONG:
422:                    long l1 = op1.longValue();
423:                    long l2 = op2.longValue();
424:                    if (l1 < l2) {
425:                        return -1;
426:                    }
427:                    if (l1 > l2) {
428:                        return 1;
429:                    }
430:                    return 0;
431:                case BASE_FLOAT:
432:                    float f1 = op1.floatValue();
433:                    float f2 = op2.floatValue();
434:                    if (f1 < f2) {
435:                        return -1;
436:                    }
437:                    if (f1 > f2) {
438:                        return 1;
439:                    }
440:                    return 0;
441:                case BASE_DOUBLE:
442:                    double d1 = op1.doubleValue();
443:                    double d2 = op2.doubleValue();
444:                    if (d1 < d2) {
445:                        return -1;
446:                    }
447:                    if (d1 > d2) {
448:                        return 1;
449:                    }
450:                    return 0;
451:
452:                    // Default is BigDecimal operation
453:                default:
454:                    return toBigDecimal(op1).compareTo(toBigDecimal(op2));
455:                }
456:            }
457:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.