Source Code Cross Referenced for BigNumber.java in  » Database-DBMS » mckoi » com » mckoi » util » 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 » Database DBMS » mckoi » com.mckoi.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * com.mckoi.util.BigNumber  26 Jul 2002
003:         *
004:         * Mckoi SQL Database ( http://www.mckoi.com/database )
005:         * Copyright (C) 2000, 2001, 2002  Diehl and Associates, Inc.
006:         *
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License
009:         * Version 2 as published by the Free Software Foundation.
010:         *
011:         * This program is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014:         * GNU General Public License Version 2 for more details.
015:         *
016:         * You should have received a copy of the GNU General Public License
017:         * Version 2 along with this program; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
019:         *
020:         * Change Log:
021:         * 
022:         * 
023:         */package com.mckoi.util;
024:
025:        import java.math.BigDecimal;
026:        import java.math.BigInteger;
027:
028:        /**
029:         * Extends BigDecimal to allow a number to be positive infinity, negative
030:         * infinity and not-a-number.  This provides compatibility with float and
031:         * double types.
032:         *
033:         * @author Tobias Downer
034:         */
035:
036:        public final class BigNumber extends Number {
037:
038:            static final long serialVersionUID = -8681578742639638105L;
039:
040:            /**
041:             * State enumerations.
042:             */
043:            private final static byte NEG_INF_STATE = 1;
044:            private final static byte POS_INF_STATE = 2;
045:            private final static byte NaN_STATE = 3;
046:
047:            /**
048:             * The state of the number, either 0 for number is the BigDecimal, 1 for
049:             * negative infinity, 2 for positive infinity and 3 for NaN.
050:             */
051:            private byte number_state;
052:
053:            /**
054:             * The BigDecimal representation.
055:             */
056:            private BigDecimal big_decimal;
057:
058:            /**
059:             * A 'long' representation of this number.
060:             */
061:            private long long_representation;
062:
063:            /**
064:             * If this can be represented as an int or long, this contains the number
065:             * of bytes needed to represent the number.
066:             */
067:            private byte byte_count = 120;
068:
069:            /**
070:             * Constructs the number.
071:             */
072:            private BigNumber(byte number_state, BigDecimal big_decimal) {
073:                this .number_state = number_state;
074:                if (number_state == 0) {
075:                    setBigDecimal(big_decimal);
076:                }
077:            }
078:
079:            private BigNumber(byte[] buf, int scale, byte state) {
080:                this .number_state = state;
081:                if (number_state == 0) {
082:                    BigInteger bigint = new BigInteger(buf);
083:                    setBigDecimal(new BigDecimal(bigint, scale));
084:                }
085:            }
086:
087:            // Only call this from a constructor!
088:            private void setBigDecimal(BigDecimal big_decimal) {
089:                this .big_decimal = big_decimal;
090:                if (big_decimal.scale() == 0) {
091:                    BigInteger bint = big_decimal.toBigInteger();
092:                    int bit_count = big_decimal.toBigInteger().bitLength();
093:                    if (bit_count < 30) {
094:                        this .long_representation = bint.longValue();
095:                        this .byte_count = 4;
096:                    } else if (bit_count < 60) {
097:                        this .long_representation = bint.longValue();
098:                        this .byte_count = 8;
099:                        ;
100:                    }
101:                }
102:            }
103:
104:            /**
105:             * Returns true if this BigNumber can be represented by a 64-bit long (has
106:             * no scale).
107:             */
108:            public boolean canBeRepresentedAsLong() {
109:                return byte_count <= 8;
110:            }
111:
112:            /**
113:             * Returns true if this BigNumber can be represented by a 32-bit int (has
114:             * no scale).
115:             */
116:            public boolean canBeRepresentedAsInt() {
117:                return byte_count <= 4;
118:            }
119:
120:            /**
121:             * Returns the scale of this number, or -1 if the number has no scale (if
122:             * it -inf, +inf or NaN).
123:             */
124:            public int getScale() {
125:                if (number_state == 0) {
126:                    return big_decimal.scale();
127:                } else {
128:                    return -1;
129:                }
130:            }
131:
132:            /**
133:             * Returns the state of this number.  Returns either 1 which indicates
134:             * negative infinity, 2 which indicates positive infinity, or 3 which
135:             * indicates NaN.
136:             */
137:            public byte getState() {
138:                return number_state;
139:            }
140:
141:            /**
142:             * Returns the inverse of the state.
143:             */
144:            private byte getInverseState() {
145:                if (number_state == NEG_INF_STATE) {
146:                    return POS_INF_STATE;
147:                } else if (number_state == POS_INF_STATE) {
148:                    return NEG_INF_STATE;
149:                } else {
150:                    return number_state;
151:                }
152:            }
153:
154:            /**
155:             * Returns this number as a byte array (unscaled).
156:             */
157:            public byte[] toByteArray() {
158:                if (number_state == 0) {
159:                    return big_decimal.movePointRight(big_decimal.scale())
160:                            .toBigInteger().toByteArray();
161:                    // [ NOTE: The following code is 1.2+ only but BigNumber should be compatible
162:                    //         with 1.1 so we use the above call ]
163:                    //    return big_decimal.unscaledValue().toByteArray();
164:                } else {
165:                    return new byte[0];
166:                }
167:            }
168:
169:            /**
170:             * Returns this big number as a string.
171:             */
172:            public String toString() {
173:                switch (number_state) {
174:                case (0):
175:                    return big_decimal.toString();
176:                case (NEG_INF_STATE):
177:                    return "-Infinity";
178:                case (POS_INF_STATE):
179:                    return "Infinity";
180:                case (NaN_STATE):
181:                    return "NaN";
182:                default:
183:                    throw new Error("Unknown number state");
184:                }
185:            }
186:
187:            /**
188:             * Returns this big number as a double.
189:             */
190:            public double doubleValue() {
191:                switch (number_state) {
192:                case (0):
193:                    return big_decimal.doubleValue();
194:                case (NEG_INF_STATE):
195:                    return Double.NEGATIVE_INFINITY;
196:                case (POS_INF_STATE):
197:                    return Double.POSITIVE_INFINITY;
198:                case (NaN_STATE):
199:                    return Double.NaN;
200:                default:
201:                    throw new Error("Unknown number state");
202:                }
203:            }
204:
205:            /**
206:             * Returns this big number as a float.
207:             */
208:            public float floatValue() {
209:                switch (number_state) {
210:                case (0):
211:                    return big_decimal.floatValue();
212:                case (NEG_INF_STATE):
213:                    return Float.NEGATIVE_INFINITY;
214:                case (POS_INF_STATE):
215:                    return Float.POSITIVE_INFINITY;
216:                case (NaN_STATE):
217:                    return Float.NaN;
218:                default:
219:                    throw new Error("Unknown number state");
220:                }
221:            }
222:
223:            /**
224:             * Returns this big number as a long.
225:             */
226:            public long longValue() {
227:                if (canBeRepresentedAsLong()) {
228:                    return long_representation;
229:                }
230:                switch (number_state) {
231:                case (0):
232:                    return big_decimal.longValue();
233:                default:
234:                    return (long) doubleValue();
235:                }
236:            }
237:
238:            /**
239:             * Returns this big number as an int.
240:             */
241:            public int intValue() {
242:                if (canBeRepresentedAsLong()) {
243:                    return (int) long_representation;
244:                }
245:                switch (number_state) {
246:                case (0):
247:                    return big_decimal.intValue();
248:                default:
249:                    return (int) doubleValue();
250:                }
251:            }
252:
253:            /**
254:             * Returns this big number as a short.
255:             */
256:            public short shortValue() {
257:                return (short) intValue();
258:            }
259:
260:            /**
261:             * Returns this big number as a byte.
262:             */
263:            public byte byteValue() {
264:                return (byte) intValue();
265:            }
266:
267:            /**
268:             * Returns the big number as a BigDecimal object.  Note that this throws
269:             * an arith error if this number represents NaN, +Inf or -Inf.
270:             */
271:            public BigDecimal asBigDecimal() {
272:                if (number_state == 0) {
273:                    return big_decimal;
274:                } else {
275:                    throw new ArithmeticException(
276:                            "NaN, +Infinity or -Infinity can't be translated to a BigDecimal");
277:                }
278:            }
279:
280:            /**
281:             * Compares this BigNumber with the given BigNumber.  Returns 0 if the values
282:             * are equal, >0 if this is greater than the given value, and &lt; 0 if this
283:             * is less than the given value.
284:             */
285:            public int compareTo(BigNumber number) {
286:
287:                if (this  == number) {
288:                    return 0;
289:                }
290:
291:                // If this is a non-infinity number
292:                if (number_state == 0) {
293:
294:                    // If both values can be represented by a long value
295:                    if (canBeRepresentedAsLong()
296:                            && number.canBeRepresentedAsLong()) {
297:                        // Perform a long comparison check,
298:                        if (long_representation > number.long_representation) {
299:                            return 1;
300:                        } else if (long_representation < number.long_representation) {
301:                            return -1;
302:                        } else {
303:                            return 0;
304:                        }
305:
306:                    }
307:
308:                    // And the compared number is non-infinity then use the BigDecimal
309:                    // compareTo method.
310:                    if (number.number_state == 0) {
311:                        return big_decimal.compareTo(number.big_decimal);
312:                    } else {
313:                        // Comparing a regular number with a NaN number.
314:                        // If positive infinity or if NaN
315:                        if (number.number_state == POS_INF_STATE
316:                                || number.number_state == NaN_STATE) {
317:                            return -1;
318:                        }
319:                        // If negative infinity
320:                        else if (number.number_state == NEG_INF_STATE) {
321:                            return 1;
322:                        } else {
323:                            throw new Error("Unknown number state.");
324:                        }
325:                    }
326:                } else {
327:                    // This number is a NaN number.
328:                    // Are we comparing with a regular number?
329:                    if (number.number_state == 0) {
330:                        // Yes, negative infinity
331:                        if (number_state == NEG_INF_STATE) {
332:                            return -1;
333:                        }
334:                        // positive infinity or NaN
335:                        else if (number_state == POS_INF_STATE
336:                                || number_state == NaN_STATE) {
337:                            return 1;
338:                        } else {
339:                            throw new Error("Unknown number state.");
340:                        }
341:                    } else {
342:                        // Comparing NaN number with a NaN number.
343:                        // This compares -Inf less than Inf and NaN and NaN greater than
344:                        // Inf and -Inf.  -Inf < Inf < NaN
345:                        return (int) (number_state - number.number_state);
346:                    }
347:                }
348:            }
349:
350:            /**
351:             * The equals comparison uses the BigDecimal 'equals' method to compare
352:             * values.  This means that '0' is NOT equal to '0.0' and '10.0' is NOT equal
353:             * to '10.00'.  Care should be taken when using this method.
354:             */
355:            public boolean equals(Object ob) {
356:                BigNumber bnum = (BigNumber) ob;
357:                if (number_state != 0) {
358:                    return (number_state == bnum.number_state);
359:                } else {
360:                    return big_decimal.equals(bnum.big_decimal);
361:                }
362:            }
363:
364:            /**
365:             * Statics.
366:             */
367:            private final static BigDecimal BD_ZERO = new BigDecimal(0);
368:
369:            // ---- Mathematical functions ----
370:
371:            public BigNumber bitWiseOr(BigNumber number) {
372:                if (number_state == 0 && getScale() == 0
373:                        && number.number_state == 0 && number.getScale() == 0) {
374:                    BigInteger bi1 = big_decimal.toBigInteger();
375:                    BigInteger bi2 = number.big_decimal.toBigInteger();
376:                    return new BigNumber((byte) 0, new BigDecimal(bi1.or(bi2)));
377:                } else {
378:                    return null;
379:                }
380:            }
381:
382:            public BigNumber add(BigNumber number) {
383:                if (number_state == 0) {
384:                    if (number.number_state == 0) {
385:                        return new BigNumber((byte) 0, big_decimal
386:                                .add(number.big_decimal));
387:                    } else {
388:                        return new BigNumber(number.number_state, null);
389:                    }
390:                } else {
391:                    return new BigNumber(number_state, null);
392:                }
393:            }
394:
395:            public BigNumber subtract(BigNumber number) {
396:                if (number_state == 0) {
397:                    if (number.number_state == 0) {
398:                        return new BigNumber((byte) 0, big_decimal
399:                                .subtract(number.big_decimal));
400:                    } else {
401:                        return new BigNumber(number.getInverseState(), null);
402:                    }
403:                } else {
404:                    return new BigNumber(number_state, null);
405:                }
406:            }
407:
408:            public BigNumber multiply(BigNumber number) {
409:                if (number_state == 0) {
410:                    if (number.number_state == 0) {
411:                        return new BigNumber((byte) 0, big_decimal
412:                                .multiply(number.big_decimal));
413:                    } else {
414:                        return new BigNumber(number.number_state, null);
415:                    }
416:                } else {
417:                    return new BigNumber(number_state, null);
418:                }
419:            }
420:
421:            public BigNumber divide(BigNumber number) {
422:                if (number_state == 0) {
423:                    if (number.number_state == 0) {
424:                        BigDecimal div_by = number.big_decimal;
425:                        if (div_by.compareTo(BD_ZERO) != 0) {
426:                            return new BigNumber((byte) 0, big_decimal.divide(
427:                                    div_by, 10, BigDecimal.ROUND_HALF_UP));
428:                        }
429:                    }
430:                }
431:                // Return NaN if we can't divide
432:                return new BigNumber((byte) 3, null);
433:            }
434:
435:            public BigNumber abs() {
436:                if (number_state == 0) {
437:                    return new BigNumber((byte) 0, big_decimal.abs());
438:                } else if (number_state == NEG_INF_STATE) {
439:                    return new BigNumber(POS_INF_STATE, null);
440:                } else {
441:                    return new BigNumber(number_state, null);
442:                }
443:            }
444:
445:            public int signum() {
446:                if (number_state == 0) {
447:                    return big_decimal.signum();
448:                } else if (number_state == NEG_INF_STATE) {
449:                    return -1;
450:                } else {
451:                    return 1;
452:                }
453:            }
454:
455:            public BigNumber setScale(int d, int round_enum) {
456:                if (number_state == 0) {
457:                    return new BigNumber((byte) 0, big_decimal.setScale(d,
458:                            round_enum));
459:                }
460:                // Can't round -inf, +inf and NaN
461:                return this ;
462:            }
463:
464:            public BigNumber sqrt() {
465:                double d = doubleValue();
466:                d = Math.sqrt(d);
467:                return fromDouble(d);
468:            }
469:
470:            // ---------- Casting from java types ----------
471:
472:            /**
473:             * Creates a BigNumber from a double.
474:             */
475:            public static BigNumber fromDouble(double value) {
476:                if (value == Double.NEGATIVE_INFINITY) {
477:                    return NEGATIVE_INFINITY;
478:                } else if (value == Double.POSITIVE_INFINITY) {
479:                    return POSITIVE_INFINITY;
480:                } else if (value != value) {
481:                    return NaN;
482:                }
483:                return new BigNumber((byte) 0, new BigDecimal(Double
484:                        .toString(value)));
485:            }
486:
487:            /**
488:             * Creates a BigNumber from a float.
489:             */
490:            public static BigNumber fromFloat(float value) {
491:                if (value == Float.NEGATIVE_INFINITY) {
492:                    return NEGATIVE_INFINITY;
493:                } else if (value == Float.POSITIVE_INFINITY) {
494:                    return POSITIVE_INFINITY;
495:                } else if (value != value) {
496:                    return NaN;
497:                }
498:                return new BigNumber((byte) 0, new BigDecimal(Float
499:                        .toString(value)));
500:            }
501:
502:            /**
503:             * Creates a BigNumber from a long.
504:             */
505:            public static BigNumber fromLong(long value) {
506:                return new BigNumber((byte) 0, BigDecimal.valueOf(value));
507:            }
508:
509:            /**
510:             * Creates a BigNumber from an int.
511:             */
512:            public static BigNumber fromInt(int value) {
513:                return new BigNumber((byte) 0, BigDecimal.valueOf(value));
514:            }
515:
516:            /**
517:             * Creates a BigNumber from a string.
518:             */
519:            public static BigNumber fromString(String str) {
520:                if (str.equals("Infinity")) {
521:                    return POSITIVE_INFINITY;
522:                } else if (str.equals("-Infinity")) {
523:                    return NEGATIVE_INFINITY;
524:                } else if (str.equals("NaN")) {
525:                    return NaN;
526:                } else {
527:                    return new BigNumber((byte) 0, new BigDecimal(str));
528:                }
529:            }
530:
531:            /**
532:             * Creates a BigNumber from a BigDecimal.
533:             */
534:            public static BigNumber fromBigDecimal(BigDecimal val) {
535:                return new BigNumber((byte) 0, val);
536:            }
537:
538:            /**
539:             * Creates a BigNumber from the given data.
540:             */
541:            public static BigNumber fromData(byte[] buf, int scale, byte state) {
542:                if (state == 0) {
543:                    // This inlines common numbers to save a bit of memory.
544:                    if (scale == 0 && buf.length == 1) {
545:                        if (buf[0] == 0) {
546:                            return BIG_NUMBER_ZERO;
547:                        } else if (buf[0] == 1) {
548:                            return BIG_NUMBER_ONE;
549:                        }
550:                    }
551:                    return new BigNumber(buf, scale, state);
552:                } else if (state == NEG_INF_STATE) {
553:                    return NEGATIVE_INFINITY;
554:                } else if (state == POS_INF_STATE) {
555:                    return POSITIVE_INFINITY;
556:                } else if (state == NaN_STATE) {
557:                    return NaN;
558:                } else {
559:                    throw new Error("Unknown number state.");
560:                }
561:            }
562:
563:            /**
564:             * Statics for negative infinity, positive infinity and NaN.
565:             */
566:            public static final BigNumber NEGATIVE_INFINITY = new BigNumber(
567:                    NEG_INF_STATE, null);
568:            public static final BigNumber POSITIVE_INFINITY = new BigNumber(
569:                    POS_INF_STATE, null);
570:            public static final BigNumber NaN = new BigNumber(NaN_STATE, null);
571:
572:            /**
573:             * Statics for 0 and 1.
574:             */
575:            public static final BigNumber BIG_NUMBER_ZERO = BigNumber
576:                    .fromLong(0);
577:            public static final BigNumber BIG_NUMBER_ONE = BigNumber
578:                    .fromLong(1);
579:
580:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.