Source Code Cross Referenced for Amount.java in  » Science » jscience-4.3.1 » org » jscience » physics » amount » 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 » Science » jscience 4.3.1 » org.jscience.physics.amount 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
0003:         * Copyright (C) 2006 - JScience (http://jscience.org/)
0004:         * All rights reserved.
0005:         * 
0006:         * Permission to use, copy, modify, and distribute this software is
0007:         * freely granted, provided that this notice is preserved.
0008:         */
0009:        package org.jscience.physics.amount;
0010:
0011:        import java.io.Serializable;
0012:
0013:        import javolution.context.ObjectFactory;
0014:        import javolution.lang.Immutable;
0015:        import javolution.lang.MathLib;
0016:        import javolution.text.Text;
0017:        import javolution.util.FastComparator;
0018:        import javolution.util.FastMap;
0019:        import javolution.xml.XMLFormat;
0020:        import javolution.xml.stream.XMLStreamException;
0021:
0022:        import org.jscience.mathematics.structure.Field;
0023:
0024:        import javax.measure.converter.ConversionException;
0025:        import javax.measure.converter.RationalConverter;
0026:        import javax.measure.converter.UnitConverter;
0027:        import javax.measure.quantity.Dimensionless;
0028:        import javax.measure.quantity.Quantity;
0029:        import javax.measure.unit.Unit;
0030:        import javax.measure.Measurable;
0031:        import javax.realtime.MemoryArea;
0032:
0033:        /**
0034:         * <p> This class represents a determinate or estimated amount for which 
0035:         *     operations such as addition, subtraction, multiplication and division
0036:         *     can be performed (it implements the {@link Field} interface).</p>
0037:         *     
0038:         * <p> The nature of an amount can be deduced from its parameterization 
0039:         *     (compile time) or its {@link #getUnit() unit} (run time).
0040:         *     Its precision is given by its {@link #getAbsoluteError() error}.</p>
0041:         *     
0042:         * <p> Amounts can be {@link #isExact() exact}, in which case they can be
0043:         *     expressed as an exact <code>long</code> integer in the amount unit.
0044:         *     The framework tries to keep amount exact as much as possible.
0045:         *     For example:[code]
0046:         *        Amount<Length> m = Amount.valueOf(33, FOOT).divide(11).times(2);
0047:         *        System.out.println(m);
0048:         *        System.out.println(m.isExact() ? "exact" : "inexact");
0049:         *        System.out.println(m.getExactValue());
0050:         *        > 6 ft
0051:         *        > exact
0052:         *        > 6[/code] 
0053:         *     </p>
0054:         *     
0055:         * <p> Errors (including numeric errors) are calculated using numeric intervals.
0056:         *     It is possible to resolve systems of linear equations involving 
0057:         *     {@link org.jscience.mathematics.vector.Matrix matrices}, even if the 
0058:         *     system is close to singularity; in which case the error associated with
0059:         *     some (or all) components of the solution may be large.</p>
0060:         *     
0061:         * <p> By default, non-exact amounts are shown using the plus/minus  
0062:         *     character ('±') (see {@link AmountFormat}). For example, 
0063:         *     <code>"(2.0 ± 0.001) km/s"</code> represents a velocity of 
0064:         *     2 km/s with an absolute error of ± 1 m/s. Exact amount use an
0065:         *     integer notation (no decimal point, e.g. <code>"2000 m"</code>).</p>
0066:         *     
0067:         * <p> Operations between different amounts may or may not be authorized 
0068:         *     based upon the current {@link org.jscience.physics.model.PhysicalModel
0069:         *     PhysicalModel}. For example, adding <code>Amount&lt;Length&gt; and 
0070:         *     <code>Amount&lt;Duration&gt; is not allowed by the 
0071:         *     {@link org.jscience.physics.model.StandardModel StandardModel}, 
0072:         *     but is authorized with the {@link
0073:         *     org.jscience.physics.model.RelativisticModel RelativisticModel}.</p>
0074:         *     
0075:         * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
0076:         * @version 4.0, June 4, 2007
0077:         * @see <a href="http://en.wikipedia.org/wiki/Measuring">
0078:         *       Wikipedia: Measuring</a>
0079:         */
0080:        public final class Amount<Q extends Quantity> implements  Measurable<Q>,
0081:                Field<Amount<?>>, Serializable, Immutable {
0082:
0083:            ////////////////////////////////////////////////////////////////////////////////
0084:            // Note: In the future, Amount might be abstract (with more measure types)   // 
0085:            //       We don't provide public constructors, factory methods should be used.//
0086:            ////////////////////////////////////////////////////////////////////////////////
0087:
0088:            /**
0089:             * Holds a dimensionless measure of zero (exact).
0090:             */
0091:            public static final Amount<Dimensionless> ZERO = new Amount<Dimensionless>();
0092:            static {
0093:                ZERO._unit = Unit.ONE;
0094:                ZERO._isExact = true;
0095:                ZERO._exactValue = 0L;
0096:                ZERO._minimum = 0;
0097:                ZERO._maximum = 0;
0098:            }
0099:
0100:            /**
0101:             * Holds a dimensionless measure of one (exact).
0102:             */
0103:            public static final Amount<Dimensionless> ONE = new Amount<Dimensionless>();
0104:            static {
0105:                ONE._unit = Unit.ONE;
0106:                ONE._isExact = true;
0107:                ONE._exactValue = 1L;
0108:                ONE._minimum = 1.0;
0109:                ONE._maximum = 1.0;
0110:            }
0111:
0112:            /**
0113:             * Holds the default XML representation for measures.
0114:             * This representation consists of a <code>value</code>, 
0115:             * an <code>unit</code> and an optional <code>error</code> attribute 
0116:             * when the measure is not exact.
0117:             * The unit attribute determinates the measurement type. For example:<pre>
0118:             * &lt;Amount value="12" unit="µA"/&gt;</pre>
0119:             * represents an electric current measurement.
0120:             */
0121:            @SuppressWarnings("unchecked")
0122:            protected static final XMLFormat<Amount> XML = new XMLFormat<Amount>(
0123:                    Amount.class) {
0124:
0125:                @Override
0126:                public Amount newInstance(Class<Amount> cls, InputElement xml)
0127:                        throws XMLStreamException {
0128:                    Unit unit = Unit.valueOf(xml.getAttribute("unit"));
0129:                    Amount<?> m = Amount.newInstance(unit);
0130:                    if (xml.getAttribute("error") == null) // Exact.
0131:                        return m.setExact(xml.getAttribute("value", 0L));
0132:                    m._isExact = false;
0133:                    double estimatedValue = xml.getAttribute("value", 0.0);
0134:                    double error = xml.getAttribute("error", 0.0);
0135:                    m._minimum = estimatedValue - error;
0136:                    m._maximum = estimatedValue + error;
0137:                    return m;
0138:                }
0139:
0140:                @Override
0141:                public void read(javolution.xml.XMLFormat.InputElement arg0,
0142:                        Amount arg1) throws XMLStreamException {
0143:                    // Nothing to do.
0144:                }
0145:
0146:                @Override
0147:                public void write(Amount m, OutputElement xml)
0148:                        throws XMLStreamException {
0149:                    if (m._isExact) {
0150:                        xml.setAttribute("value", m._exactValue);
0151:                    } else {
0152:                        xml.setAttribute("value", m.getEstimatedValue());
0153:                        xml.setAttribute("error", m.getAbsoluteError());
0154:                    }
0155:                    xml.setAttribute("unit", m._unit.toString());
0156:                }
0157:            };
0158:
0159:            /**
0160:             * Returns the exact measure corresponding to the value stated in the 
0161:             * specified unit.
0162:             *
0163:             * @param value the exact value stated in the specified unit.
0164:             * @param unit the unit in which the value is stated.
0165:             * @return the corresponding measure object.
0166:             */
0167:            public static <Q extends Quantity> Amount<Q> valueOf(long value,
0168:                    Unit<Q> unit) {
0169:                Amount<Q> m = Amount.newInstance(unit);
0170:                return m.setExact(value);
0171:            }
0172:
0173:            /**
0174:             * Returns the measure corresponding to an approximate value 
0175:             * (<code>double</code>) stated in the specified unit; 
0176:             * the precision of the measure is assumed to be the 
0177:             * <code>double</code> precision (64 bits IEEE 754 format).
0178:             *
0179:             * @param value the estimated value (± LSB) stated in the specified unit.
0180:             * @param unit the unit in which the value is stated.
0181:             * @return the corresponding measure object.
0182:             */
0183:            public static <Q extends Quantity> Amount<Q> valueOf(double value,
0184:                    Unit<Q> unit) {
0185:                Amount<Q> m = Amount.newInstance(unit);
0186:                m._isExact = false;
0187:                double valInc = value * INCREMENT;
0188:                double valDec = value * DECREMENT;
0189:                m._minimum = (value < 0) ? valInc : valDec;
0190:                m._maximum = (value < 0) ? valDec : valInc;
0191:                return m;
0192:            }
0193:
0194:            /**
0195:             * Returns the measure corresponding to the specified approximate value 
0196:             * and measurement error, both stated in the specified unit.
0197:             *
0198:             * @param value the estimated amount (± error) stated in the specified unit.
0199:             * @param error the measurement error (absolute).
0200:             * @param unit the unit in which the amount and the error are stated.
0201:             * @return the corresponding measure object.
0202:             * @throws IllegalArgumentException if <code>error &lt; 0.0</code>
0203:             */
0204:            public static <Q extends Quantity> Amount<Q> valueOf(double value,
0205:                    double error, Unit<Q> unit) {
0206:                if (error < 0)
0207:                    throw new IllegalArgumentException("error: " + error
0208:                            + " is negative");
0209:                Amount<Q> m = Amount.newInstance(unit);
0210:                double min = value - error;
0211:                double max = value + error;
0212:                m._isExact = false;
0213:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0214:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0215:                return m;
0216:            }
0217:
0218:            /**
0219:             * Returns the measure corresponding to the specified interval stated 
0220:             * in the specified unit.
0221:             *
0222:             * @param  minimum the lower bound for the measure value.
0223:             * @param  maximum the upper bound for the measure value.
0224:             * @param unit the unit for both the minimum and maximum values.
0225:             * @return the corresponding measure object.
0226:             * @throws IllegalArgumentException if <code>minimum &gt; maximum</code>
0227:             */
0228:            public static <Q extends Quantity> Amount<Q> rangeOf(
0229:                    double minimum, double maximum, Unit<Q> unit) {
0230:                if (minimum > maximum)
0231:                    throw new IllegalArgumentException("minimum: " + minimum
0232:                            + " greater than maximum: " + maximum);
0233:                Amount<Q> m = Amount.newInstance(unit);
0234:                m._isExact = false;
0235:                m._minimum = (minimum < 0) ? minimum * INCREMENT : minimum
0236:                        * DECREMENT;
0237:                m._maximum = (maximum < 0) ? maximum * DECREMENT : maximum
0238:                        * INCREMENT;
0239:                return m;
0240:            }
0241:
0242:            /**
0243:             * Returns the measure represented by the specified character sequence.
0244:             *
0245:             * @param csq the character sequence.
0246:             * @return <code>AmountFormat.getInstance().parse(csq)</code>
0247:             */
0248:            public static Amount<?> valueOf(CharSequence csq) {
0249:                return AmountFormat.getInstance().parse(csq);
0250:            }
0251:
0252:            /**
0253:             * Indicates if this measure is exact.
0254:             */
0255:            private boolean _isExact;
0256:
0257:            /**
0258:             * Holds the exact value (when exact) stated in this measure unit.
0259:             */
0260:            private long _exactValue;
0261:
0262:            /**
0263:             * Holds the minimum value stated in this measure unit.
0264:             * For inexact measures: _minimum < _maximum 
0265:             */
0266:            private double _minimum;
0267:
0268:            /**
0269:             * Holds the maximum value stated in this measure unit.
0270:             * For inexact measures: _maximum > _minimum 
0271:             */
0272:            private double _maximum;
0273:
0274:            /**
0275:             * Holds this measure unit. 
0276:             */
0277:            private Unit<Q> _unit;
0278:
0279:            /**
0280:             * Indicates if this measure amount is exact. An exact amount is 
0281:             * guarantee exact only when stated in this measure unit
0282:             * (e.g. <code>this.longValue()</code>); stating the amount
0283:             * in any other unit may introduce conversion errors. 
0284:             *
0285:             * @return <code>true</code> if this measure is exact;
0286:             *         <code>false</code> otherwise.
0287:             */
0288:            public boolean isExact() {
0289:                return _isExact;
0290:            }
0291:
0292:            /**
0293:             * Returns the unit in which the {@link #getEstimatedValue()
0294:             * estimated value} and {@link #getAbsoluteError() absolute error}
0295:             * are stated.
0296:             *
0297:             * @return the measure unit.
0298:             */
0299:            public Unit<Q> getUnit() {
0300:                return _unit;
0301:            }
0302:
0303:            /**
0304:             * Returns the exact value for this measure stated in this measure
0305:             * {@link #getUnit unit}. 
0306:             *
0307:             * @return the exact measure value (<code>long</code>) stated 
0308:             *         in this measure's {@link #getUnit unit}
0309:             * @throws AmountException if this measure is not {@link #isExact()}
0310:             */
0311:            public long getExactValue() throws AmountException {
0312:                if (!_isExact)
0313:                    throw new AmountException(
0314:                            "Inexact measures don't have exact values");
0315:                return _exactValue;
0316:            }
0317:
0318:            /**
0319:             * Returns the estimated value for this measure stated in this measure
0320:             * {@link #getUnit unit}. 
0321:             *
0322:             * @return the median value of the measure interval.
0323:             */
0324:            public double getEstimatedValue() {
0325:                return (_isExact) ? _exactValue : (_minimum + _maximum) * 0.5;
0326:            }
0327:
0328:            /**
0329:             * Returns the lower bound interval value for this measure stated in 
0330:             * this measure unit.
0331:             *
0332:             * @return the minimum value.
0333:             */
0334:            public double getMinimumValue() {
0335:                return _minimum;
0336:            }
0337:
0338:            /**
0339:             * Returns the upper bound interval value for this measure stated in 
0340:             * this measure unit.
0341:             *
0342:             * @return the maximum value.
0343:             */
0344:            public double getMaximumValue() {
0345:                return _maximum;
0346:            }
0347:
0348:            /**
0349:             * Returns the value by which the{@link #getEstimatedValue() estimated 
0350:             * value} may differ from the true value (all stated in base units).
0351:             *
0352:             * @return the absolute error stated in base units.
0353:             */
0354:            public double getAbsoluteError() {
0355:                return MathLib.abs(_maximum - _minimum) * 0.5;
0356:            }
0357:
0358:            /**
0359:             * Returns the percentage by which the estimated amount may differ
0360:             * from the true amount.
0361:             *
0362:             * @return the relative error.
0363:             */
0364:            public double getRelativeError() {
0365:                return _isExact ? 0 : (_maximum - _minimum)
0366:                        / (_minimum + _maximum);
0367:            }
0368:
0369:            /**
0370:             * Returns the measure equivalent to this measure but stated in the 
0371:             * specified unit. The returned measure may not be exact even if this 
0372:             * measure is exact due to conversion errors. 
0373:             *
0374:             * @param  unit the unit of the measure to be returned.
0375:             * @return a measure equivalent to this measure but stated in the 
0376:             *         specified unit.
0377:             * @throws ConversionException if the current model does not allows for
0378:             *         conversion to the specified unit.
0379:             */
0380:            @SuppressWarnings("unchecked")
0381:            public <R extends Quantity> Amount<R> to(Unit<R> unit) {
0382:                if ((_unit == unit) || this ._unit.equals(unit))
0383:                    return (Amount<R>) this ;
0384:                UnitConverter cvtr = Amount.converterOf(_unit, unit);
0385:                if (cvtr == UnitConverter.IDENTITY) { // No conversion necessary.
0386:                    Amount result = Amount.copyOf(this );
0387:                    result._unit = unit;
0388:                    return result;
0389:                }
0390:                if (cvtr instanceof  RationalConverter) { // Exact conversion.
0391:                    RationalConverter rc = (RationalConverter) cvtr;
0392:                    Amount result = this .times(rc.getDividend()).divide(
0393:                            rc.getDivisor());
0394:                    result._unit = unit;
0395:                    return result;
0396:                }
0397:                Amount<R> result = Amount.newInstance(unit);
0398:                double min = cvtr.convert(_minimum);
0399:                double max = cvtr.convert(_maximum);
0400:                result._isExact = false;
0401:                result._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0402:                result._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0403:                return result;
0404:            }
0405:
0406:            /**
0407:             * Returns the opposite of this measure.
0408:             *
0409:             * @return <code>-this</code>.
0410:             */
0411:            public Amount<Q> opposite() {
0412:                Amount<Q> m = Amount.newInstance(_unit);
0413:                if ((_isExact) && (_exactValue != Long.MAX_VALUE))
0414:                    return m.setExact(-_exactValue);
0415:                m._isExact = false;
0416:                m._minimum = -_maximum;
0417:                m._maximum = -_minimum;
0418:                return m;
0419:            }
0420:
0421:            /**
0422:             * Returns the sum of this measure with the one specified.
0423:             *
0424:             * @param  that the measure to be added.
0425:             * @return <code>this + that</code>.
0426:             * @throws ConversionException if the current model does not allows for
0427:             *         these quantities to be added.
0428:             */
0429:            @SuppressWarnings("unchecked")
0430:            public Amount<Q> plus(Amount that) throws ConversionException {
0431:                final Amount thatToUnit = that.to(_unit);
0432:                Amount<Q> m = Amount.newInstance(_unit);
0433:                if (this ._isExact && thatToUnit._isExact) {
0434:                    long sumLong = this ._exactValue + thatToUnit._exactValue;
0435:                    double sumDouble = ((double) this ._exactValue)
0436:                            + ((double) thatToUnit._exactValue);
0437:                    if (sumLong == sumDouble)
0438:                        return m.setExact(sumLong);
0439:                }
0440:                double min = this ._minimum + thatToUnit._minimum;
0441:                double max = this ._maximum + thatToUnit._maximum;
0442:                m._isExact = false;
0443:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0444:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0445:                return m;
0446:            }
0447:
0448:            /**
0449:             * Returns the difference of this measure with the one specified.
0450:             *
0451:             * @param  that the measure to be subtracted.
0452:             * @return <code>this - that</code>.
0453:             * @throws ConversionException if the current model does not allows for
0454:             *         these quantities to be subtracted.
0455:             */
0456:            @SuppressWarnings("unchecked")
0457:            public Amount<Q> minus(Amount that) throws ConversionException {
0458:                final Amount thatToUnit = that.to(_unit);
0459:                Amount<Q> m = Amount.newInstance(_unit);
0460:                if (this ._isExact && thatToUnit._isExact) {
0461:                    long diffLong = this ._exactValue - thatToUnit._exactValue;
0462:                    double diffDouble = ((double) this ._exactValue)
0463:                            - ((double) thatToUnit._exactValue);
0464:                    if (diffLong == diffDouble)
0465:                        return m.setExact(diffLong);
0466:                }
0467:                double min = this ._minimum - thatToUnit._maximum;
0468:                double max = this ._maximum - thatToUnit._minimum;
0469:                m._isExact = false;
0470:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0471:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0472:                return m;
0473:            }
0474:
0475:            /**
0476:             * Returns this measure scaled by the specified exact factor 
0477:             * (dimensionless).
0478:             *
0479:             * @param  factor the scaling factor.
0480:             * @return <code>this · factor</code>.
0481:             */
0482:            public Amount<Q> times(long factor) {
0483:                Amount<Q> m = Amount.newInstance(_unit);
0484:                if (this ._isExact) {
0485:                    long productLong = _exactValue * factor;
0486:                    double productDouble = ((double) _exactValue) * factor;
0487:                    if (productLong == productDouble)
0488:                        return m.setExact(productLong);
0489:                }
0490:                m._isExact = false;
0491:                m._minimum = (factor > 0) ? _minimum * factor : _maximum
0492:                        * factor;
0493:                m._maximum = (factor > 0) ? _maximum * factor : _minimum
0494:                        * factor;
0495:                return m;
0496:            }
0497:
0498:            /**
0499:             * Returns this measure scaled by the specified approximate factor
0500:             * (dimensionless).
0501:             *
0502:             * @param  factor the scaling factor.
0503:             * @return <code>this · factor</code>.
0504:             */
0505:            public Amount<Q> times(double factor) {
0506:                Amount<Q> m = Amount.newInstance(_unit);
0507:                double min = (factor > 0) ? _minimum * factor : _maximum
0508:                        * factor;
0509:                double max = (factor > 0) ? _maximum * factor : _minimum
0510:                        * factor;
0511:                m._isExact = false;
0512:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0513:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0514:                return m;
0515:            }
0516:
0517:            /**
0518:             * Returns the product of this measure with the one specified.
0519:             *
0520:             * @param  that the measure multiplier.
0521:             * @return <code>this · that</code>.
0522:             */
0523:            @SuppressWarnings("unchecked")
0524:            public Amount<? extends Quantity> times(Amount that) {
0525:                Unit<?> unit = Amount.productOf(this ._unit, that._unit);
0526:                if (that._isExact) {
0527:                    Amount m = this .times(that._exactValue);
0528:                    m._unit = unit;
0529:                    return m;
0530:                }
0531:                Amount<Q> m = Amount.newInstance(unit);
0532:                double min, max;
0533:                if (_minimum >= 0) {
0534:                    if (that._minimum >= 0) {
0535:                        min = _minimum * that._minimum;
0536:                        max = _maximum * that._maximum;
0537:                    } else if (that._maximum < 0) {
0538:                        min = _maximum * that._minimum;
0539:                        max = _minimum * that._maximum;
0540:                    } else {
0541:                        min = _maximum * that._minimum;
0542:                        max = _maximum * that._maximum;
0543:                    }
0544:                } else if (_maximum < 0) {
0545:                    if (that._minimum >= 0) {
0546:                        min = _minimum * that._maximum;
0547:                        max = _maximum * that._minimum;
0548:                    } else if (that._maximum < 0) {
0549:                        min = _maximum * that._maximum;
0550:                        max = _minimum * that._minimum;
0551:                    } else {
0552:                        min = _minimum * that._maximum;
0553:                        max = _minimum * that._minimum;
0554:                    }
0555:                } else {
0556:                    if (that._minimum >= 0) {
0557:                        min = _minimum * that._maximum;
0558:                        max = _maximum * that._maximum;
0559:                    } else if (that._maximum < 0) {
0560:                        min = _maximum * that._minimum;
0561:                        max = _minimum * that._minimum;
0562:                    } else { // Both around zero.
0563:                        min = MathLib.min(_minimum * that._maximum, _maximum
0564:                                * that._minimum);
0565:                        max = MathLib.max(_minimum * that._minimum, _maximum
0566:                                * that._maximum);
0567:                    }
0568:                }
0569:                m._isExact = false;
0570:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0571:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0572:                return m;
0573:            }
0574:
0575:            /**
0576:             * Returns the multiplicative inverse of this measure.
0577:             * If this measure is possibly zero, then the result is unbounded
0578:             * (]-infinity, +infinity[).
0579:             *
0580:             * @return <code>1 / this</code>.
0581:             */
0582:            public Amount<? extends Quantity> inverse() {
0583:                Amount<? extends Quantity> m = newInstance(Amount
0584:                        .inverseOf(_unit));
0585:                if ((_isExact) && (_exactValue == 1L)) { // Only one exact inverse: one
0586:                    m.setExact(1L);
0587:                    return m;
0588:                }
0589:                m._isExact = false;
0590:                if ((_minimum <= 0) && (_maximum >= 0)) { // Encompass zero.
0591:                    m._minimum = Double.NEGATIVE_INFINITY;
0592:                    m._maximum = Double.POSITIVE_INFINITY;
0593:                    return m;
0594:                }
0595:                double min = 1.0 / _maximum;
0596:                double max = 1.0 / _minimum;
0597:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0598:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0599:                return m;
0600:            }
0601:
0602:            /**
0603:             * Returns this measure divided by the specified exact divisor
0604:             * (dimensionless).
0605:             *
0606:             * @param  divisor the exact divisor.
0607:             * @return <code>this / divisor</code>.
0608:             * @throws ArithmeticException if this measure is exact and the 
0609:             *         specified divisor is zero.
0610:             */
0611:            public Amount<Q> divide(long divisor) {
0612:                Amount<Q> m = Amount.newInstance(_unit);
0613:                if (this ._isExact) {
0614:                    long quotientLong = _exactValue / divisor;
0615:                    double quotientDouble = ((double) _exactValue) / divisor;
0616:                    if (quotientLong == quotientDouble)
0617:                        return m.setExact(quotientLong);
0618:                }
0619:                double min = (divisor > 0) ? _minimum / divisor : _maximum
0620:                        / divisor;
0621:                double max = (divisor > 0) ? _maximum / divisor : _minimum
0622:                        / divisor;
0623:                m._isExact = false;
0624:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0625:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0626:                return m;
0627:            }
0628:
0629:            /**
0630:             * Returns this measure divided by the specified approximate divisor
0631:             * (dimensionless).
0632:             *
0633:             * @param  divisor the approximated divisor.
0634:             * @return <code>this / divisor</code>.
0635:             */
0636:            public Amount<Q> divide(double divisor) {
0637:                Amount<Q> m = Amount.newInstance(_unit);
0638:                double min = (divisor > 0) ? _minimum / divisor : _maximum
0639:                        / divisor;
0640:                double max = (divisor > 0) ? _maximum / divisor : _minimum
0641:                        / divisor;
0642:                m._isExact = false;
0643:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0644:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0645:                return m;
0646:            }
0647:
0648:            /**
0649:             * Returns this measure divided by the one specified.
0650:             *
0651:             * @param  that the measure divisor.
0652:             * @return <code>this / that</code>.
0653:             */
0654:            @SuppressWarnings("unchecked")
0655:            public Amount<? extends Quantity> divide(Amount that) {
0656:                if (that._isExact) {
0657:                    Amount m = this .divide(that._exactValue);
0658:                    m._unit = Amount.productOf(this ._unit, Amount
0659:                            .inverseOf(that._unit));
0660:                    return m;
0661:                }
0662:                return this .times(that.inverse());
0663:            }
0664:
0665:            /**
0666:             * Returns the absolute value of this measure.
0667:             *
0668:             * @return  <code>|this|</code>.
0669:             */
0670:            public Amount<Q> abs() {
0671:                return (_isExact) ? ((_exactValue < 0) ? this .opposite() : this )
0672:                        : (_minimum >= -_maximum) ? this  : this .opposite();
0673:            }
0674:
0675:            /**
0676:             * Returns the square root of this measure.
0677:             *
0678:             * @return <code>sqrt(this)</code>
0679:             * 
0680:             */
0681:            public Amount<? extends Quantity> sqrt() {
0682:                Amount<Q> m = Amount.newInstance(_unit.root(2));
0683:                if (this ._isExact) {
0684:                    double sqrtDouble = MathLib.sqrt(_exactValue);
0685:                    long sqrtLong = (long) sqrtDouble;
0686:                    if (sqrtLong * sqrtLong == _exactValue)
0687:                        return m.setExact(sqrtLong);
0688:                }
0689:                double min = MathLib.sqrt(_minimum);
0690:                double max = MathLib.sqrt(_maximum);
0691:                m._isExact = false;
0692:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0693:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0694:                return m;
0695:            }
0696:
0697:            /**
0698:             * Returns the given root of this measure.
0699:             *
0700:             * @param  n the root's order (n != 0).
0701:             * @return the result of taking the given root of this quantity.
0702:             * @throws ArithmeticException if <code>n == 0</code>.
0703:             */
0704:            public Amount<? extends Quantity> root(int n) {
0705:                if (n == 0)
0706:                    throw new ArithmeticException("Root's order of zero");
0707:                if (n < 0)
0708:                    return this .root(-n).inverse();
0709:                if (n == 2)
0710:                    return this .sqrt();
0711:                Amount<Q> m = Amount.newInstance(_unit.root(n));
0712:                if (this ._isExact) {
0713:                    double rootDouble = MathLib.pow(_exactValue, 1.0 / n);
0714:                    long rootLong = (long) rootDouble;
0715:                    long this Long = rootLong;
0716:                    for (int i = 1; i < n; i++) {
0717:                        this Long *= rootLong;
0718:                    }
0719:                    if (this Long == _exactValue)
0720:                        return m.setExact(rootLong);
0721:                }
0722:                double min = MathLib.pow(_minimum, 1.0 / n);
0723:                double max = MathLib.pow(_maximum, 1.0 / n);
0724:                m._isExact = false;
0725:                m._minimum = (min < 0) ? min * INCREMENT : min * DECREMENT;
0726:                m._maximum = (max < 0) ? max * DECREMENT : max * INCREMENT;
0727:                return m;
0728:            }
0729:
0730:            /**
0731:             * Returns this measure raised at the specified exponent.
0732:             *
0733:             * @param  exp the exponent.
0734:             * @return <code>this<sup>exp</sup></code>
0735:             */
0736:            public Amount<? extends Quantity> pow(int exp) {
0737:                if (exp < 0)
0738:                    return this .pow(-exp).inverse();
0739:                if (exp == 0)
0740:                    return ONE;
0741:                Amount<?> pow2 = this ;
0742:                Amount<?> result = null;
0743:                while (exp >= 1) { // Iteration.
0744:                    if ((exp & 1) == 1) {
0745:                        result = (result == null) ? pow2 : result.times(pow2);
0746:                    }
0747:                    pow2 = pow2.times(pow2);
0748:                    exp >>>= 1;
0749:                }
0750:                return result;
0751:            }
0752:
0753:            /**
0754:             * Compares this measure with the specified measurable object.
0755:             *
0756:             * @param  that the measure to compare with.
0757:             * @return a negative integer, zero, or a positive integer as this measure
0758:             *         is less than, equal to, or greater than that measurable.
0759:             * @throws ConversionException if the current model does not allows for
0760:             *         these measure to be compared.
0761:             */
0762:            @SuppressWarnings("unchecked")
0763:            public int compareTo(Measurable<Q> that) {
0764:                double thatValue = that.doubleValue(_unit);
0765:                return Double.compare(this .getEstimatedValue(), thatValue);
0766:            }
0767:
0768:            /**
0769:             * Compares this measure against the specified object for strict 
0770:             * equality (same value interval and same units).
0771:             *
0772:             * @param  that the object to compare with.
0773:             * @return <code>true</code> if this measure is identical to that
0774:             *         measure; <code>false</code> otherwise.
0775:             */
0776:            public boolean equals(Object that) {
0777:                if (this  == that)
0778:                    return true;
0779:                if (!(that instanceof  Amount<?>))
0780:                    return false;
0781:                Amount<?> m = (Amount<?>) that;
0782:                if (!_unit.equals(m._unit))
0783:                    return false;
0784:                if (_isExact != m._isExact)
0785:                    return false;
0786:                if (_isExact && (this ._exactValue == m._exactValue))
0787:                    return true;
0788:                if (_minimum != m._minimum)
0789:                    return false;
0790:                if (_maximum != m._maximum)
0791:                    return false;
0792:                return true;
0793:            }
0794:
0795:            /**
0796:             * Returns the hash code for this measure.
0797:             * 
0798:             * @return the hash code value.
0799:             */
0800:            public int hashCode() {
0801:                int h = Float.floatToIntBits((float) _minimum);
0802:                h += ~(h << 9);
0803:                h ^= (h >>> 14);
0804:                h += (h << 4);
0805:                return h ^ (h >>> 10);
0806:            }
0807:
0808:            /**
0809:             * Indicates if this measure approximates that measure.
0810:             * Measures are considered approximately equals if their value intervals
0811:             * overlaps. It should be noted that less accurate measurements are 
0812:             * more likely to be approximately equals. It is therefore recommended
0813:             * to ensure that the measurement error is not too large before testing
0814:             * for approximate equality.
0815:             *
0816:             * @return <code>this ≅ that</code>
0817:             */
0818:            @SuppressWarnings("unchecked")
0819:            public boolean approximates(Amount that) {
0820:                Amount thatToUnit = that.to(_unit);
0821:                return (this ._maximum >= thatToUnit._minimum)
0822:                        && (thatToUnit._maximum >= this ._minimum);
0823:            }
0824:
0825:            /**
0826:             * Indicates if this measure is ordered before that measure
0827:             * (independently of the measure unit).
0828:             *
0829:             * @return <code>this.compareTo(that) < 0</code>.
0830:             */
0831:            public boolean isLessThan(Amount<Q> that) {
0832:                return this .compareTo(that) < 0;
0833:            }
0834:
0835:            /**
0836:             * Indicates if this measure is ordered after that measure
0837:             * (independently of the measure unit).
0838:             *
0839:             * @return <code>this.compareTo(that) > 0</code>.
0840:             */
0841:            public boolean isGreaterThan(Amount<Q> that) {
0842:                return this .compareTo(that) > 0;
0843:            }
0844:
0845:            /**
0846:             * Compares this measure with that measure ignoring the sign.
0847:             *
0848:             * @return <code>|this| > |that|</code>
0849:             */
0850:            public boolean isLargerThan(Amount<Q> that) {
0851:                return this .abs().isGreaterThan(that.abs());
0852:            }
0853:
0854:            /**
0855:             * Returns the text representation of this measure.
0856:             *
0857:             * @return <code>AmountFormat.getInstance().format(this)</code>
0858:             */
0859:            public Text toText() {
0860:                return AmountFormat.getInstance().format(this );
0861:            }
0862:
0863:            /**
0864:             * Returns the text representation of this amount as a 
0865:             * <code>java.lang.String</code>.
0866:             * 
0867:             * @return <code>toText().toString()</code>
0868:             */
0869:            public final String toString() {
0870:                return toText().toString();
0871:            }
0872:
0873:            // Implements Quantity.
0874:            public double doubleValue(Unit<Q> unit) {
0875:                return ((_unit == unit) || _unit.equals(unit)) ? this 
0876:                        .getEstimatedValue() : this .to(unit)
0877:                        .getEstimatedValue();
0878:            }
0879:
0880:            // Implements Quantity.
0881:            public final long longValue(Unit<Q> unit) {
0882:                if (!_unit.equals(unit))
0883:                    return this .to(unit).longValue(unit);
0884:                if (_isExact)
0885:                    return _exactValue;
0886:                double doubleValue = this .getEstimatedValue();
0887:                if ((doubleValue >= Long.MIN_VALUE)
0888:                        && (doubleValue <= Long.MAX_VALUE))
0889:                    return Math.round(doubleValue);
0890:                throw new ArithmeticException(doubleValue + " " + _unit
0891:                        + " cannot be represented as long");
0892:            }
0893:
0894:            ///////////////////
0895:            // Lookup tables //
0896:            ///////////////////
0897:
0898:            static final FastMap<Unit<?>, FastMap<Unit<?>, Unit<?>>> MULT_LOOKUP = new FastMap<Unit<?>, FastMap<Unit<?>, Unit<?>>>(
0899:                    "UNITS_MULT_LOOKUP")
0900:                    .setKeyComparator(FastComparator.DIRECT);
0901:
0902:            static final FastMap<Unit<?>, Unit<?>> INV_LOOKUP = new FastMap<Unit<?>, Unit<?>>(
0903:                    "UNITS_INV_LOOKUP").setKeyComparator(FastComparator.DIRECT);
0904:
0905:            static final FastMap<Unit<?>, FastMap<Unit<?>, UnitConverter>> CVTR_LOOKUP = new FastMap<Unit<?>, FastMap<Unit<?>, UnitConverter>>(
0906:                    "UNITS_CVTR_LOOKUP")
0907:                    .setKeyComparator(FastComparator.DIRECT);
0908:
0909:            private static Unit<?> productOf(Unit<?> left, Unit<?> right) {
0910:                FastMap<Unit<?>, Unit<?>> leftTable = MULT_LOOKUP.get(left);
0911:                if (leftTable == null)
0912:                    return calculateProductOf(left, right);
0913:                Unit<?> result = leftTable.get(right);
0914:                if (result == null)
0915:                    return calculateProductOf(left, right);
0916:                return result;
0917:            }
0918:
0919:            private static synchronized Unit<?> calculateProductOf(
0920:                    final Unit<?> left, final Unit<?> right) {
0921:                MemoryArea memoryArea = MemoryArea.getMemoryArea(MULT_LOOKUP);
0922:                memoryArea.executeInArea(new Runnable() {
0923:                    public void run() {
0924:                        FastMap<Unit<?>, Unit<?>> leftTable = MULT_LOOKUP
0925:                                .get(left);
0926:                        if (leftTable == null) {
0927:                            leftTable = new FastMap<Unit<?>, Unit<?>>()
0928:                                    .setKeyComparator(FastComparator.DIRECT);
0929:                            MULT_LOOKUP.put(left, leftTable);
0930:                        }
0931:                        Unit<?> result = leftTable.get(right);
0932:                        if (result == null) {
0933:                            result = left.times(right);
0934:                            leftTable.put(right, result);
0935:                        }
0936:                    }
0937:                });
0938:                return MULT_LOOKUP.get(left).get(right);
0939:            }
0940:
0941:            private static Unit<?> inverseOf(Unit<?> unit) {
0942:                Unit<?> inverse = INV_LOOKUP.get(unit);
0943:                if (inverse == null)
0944:                    return calculateInverseOf(unit);
0945:                return inverse;
0946:            }
0947:
0948:            private static synchronized Unit<?> calculateInverseOf(
0949:                    final Unit<?> unit) {
0950:                MemoryArea memoryArea = MemoryArea.getMemoryArea(INV_LOOKUP);
0951:                memoryArea.executeInArea(new Runnable() {
0952:                    public void run() {
0953:                        Unit<?> inverse = INV_LOOKUP.get(unit);
0954:                        if (inverse == null) {
0955:                            inverse = unit.inverse();
0956:                            INV_LOOKUP.put(unit, inverse);
0957:                        }
0958:                    }
0959:                });
0960:                return INV_LOOKUP.get(unit);
0961:            }
0962:
0963:            private static UnitConverter converterOf(Unit<?> left, Unit<?> right) {
0964:                FastMap<Unit<?>, UnitConverter> leftTable = CVTR_LOOKUP
0965:                        .get(left);
0966:                if (leftTable == null)
0967:                    return calculateConverterOf(left, right);
0968:                UnitConverter result = leftTable.get(right);
0969:                if (result == null)
0970:                    return calculateConverterOf(left, right);
0971:                return result;
0972:            }
0973:
0974:            private static synchronized UnitConverter calculateConverterOf(
0975:                    final Unit<?> left, final Unit<?> right) {
0976:                MemoryArea memoryArea = MemoryArea.getMemoryArea(CVTR_LOOKUP);
0977:                memoryArea.executeInArea(new Runnable() {
0978:                    public void run() {
0979:                        FastMap<Unit<?>, UnitConverter> leftTable = CVTR_LOOKUP
0980:                                .get(left);
0981:                        if (leftTable == null) {
0982:                            leftTable = new FastMap<Unit<?>, UnitConverter>()
0983:                                    .setKeyComparator(FastComparator.DIRECT);
0984:                            synchronized (CVTR_LOOKUP) {
0985:                                CVTR_LOOKUP.put(left, leftTable);
0986:                            }
0987:                        }
0988:                        UnitConverter result = leftTable.get(right);
0989:                        if (result == null) {
0990:                            result = left.getConverterTo(right);
0991:                            synchronized (leftTable) {
0992:                                leftTable.put(right, result);
0993:                            }
0994:                        }
0995:                    }
0996:                });
0997:                return CVTR_LOOKUP.get(left).get(right);
0998:            }
0999:
1000:            public Amount<Q> copy() {
1001:                Amount<Q> estimate = Amount.newInstance(_unit);
1002:                estimate._isExact = _isExact;
1003:                estimate._exactValue = _exactValue;
1004:                estimate._minimum = _minimum;
1005:                estimate._maximum = _maximum;
1006:                return estimate;
1007:            }
1008:
1009:            //////////////////////
1010:            // Factory Creation //
1011:            //////////////////////
1012:
1013:            @SuppressWarnings("unchecked")
1014:            private static <Q extends Quantity> Amount<Q> newInstance(
1015:                    Unit<?> unit) {
1016:                Amount<Q> measure = FACTORY.object();
1017:                measure._unit = (Unit<Q>) unit;
1018:                return measure;
1019:            }
1020:
1021:            @SuppressWarnings("unchecked")
1022:            private static <Q extends Quantity> Amount<Q> copyOf(Amount original) {
1023:                Amount<Q> measure = FACTORY.object();
1024:                measure._exactValue = original._exactValue;
1025:                measure._isExact = original._isExact;
1026:                measure._maximum = original._maximum;
1027:                measure._minimum = original._minimum;
1028:                measure._unit = original._unit;
1029:                return measure;
1030:            }
1031:
1032:            @SuppressWarnings("unchecked")
1033:            private static final ObjectFactory<Amount> FACTORY = new ObjectFactory<Amount>() {
1034:
1035:                @Override
1036:                protected Amount create() {
1037:                    return new Amount();
1038:                }
1039:            };
1040:
1041:            private Amount() {
1042:            }
1043:
1044:            private Amount<Q> setExact(long exactValue) {
1045:                _isExact = true;
1046:                _exactValue = exactValue;
1047:                double doubleValue = exactValue;
1048:                if (doubleValue == exactValue) {
1049:                    _minimum = doubleValue;
1050:                    _maximum = doubleValue;
1051:                } else {
1052:                    double valInc = exactValue * INCREMENT;
1053:                    double valDec = exactValue * DECREMENT;
1054:                    _minimum = (_exactValue < 0) ? valInc : valDec;
1055:                    _maximum = (_exactValue < 0) ? valDec : valInc;
1056:                }
1057:                return this ;
1058:            }
1059:
1060:            static final double DOUBLE_RELATIVE_ERROR = MathLib.pow(2, -53);
1061:
1062:            static final double DECREMENT = (1.0 - DOUBLE_RELATIVE_ERROR);
1063:
1064:            static final double INCREMENT = (1.0 + DOUBLE_RELATIVE_ERROR);
1065:
1066:            private static final long serialVersionUID = 1L;
1067:
1068:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.