001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.common.math;
025
026 import java.math.BigDecimal;
027 import java.util.Comparator;
028 import java.util.Random;
029 import java.util.concurrent.TimeUnit;
030
031 public class DurationOperations implements MathOperations<Duration>, Comparator<Duration> {
032
033 public Class<Duration> getOperandClass() {
034 return Duration.class;
035 }
036
037 public Duration add( Duration value1, Duration value2 ) {
038 if (value1 == null) return value2 != null ? value2 : createZeroValue();
039 if (value2 == null) return value1;
040 return value1.add(value2);
041 }
042
043 public Duration subtract( Duration value1, Duration value2 ) {
044 if (value1 == null) return negate(value2);
045 if (value2 == null) return value1;
046 return value1.subtract(value2);
047 }
048
049 public Duration multiply( Duration value1, Duration value2 ) {
050 if (value1 == null || value2 == null) return createZeroValue();
051 return value1.multiply(value2.longValue());
052 }
053
054 public double divide( Duration value1, Duration value2 ) {
055 if (value1 == null || value2 == null) throw new IllegalArgumentException();
056 return value1.divide(value2);
057 }
058
059 public Duration negate( Duration value ) {
060 if (value == null) return createZeroValue();
061 return value.multiply(value.longValue() * -1);
062 }
063
064 public Duration increment( Duration value ) {
065 if (value == null) return createZeroValue();
066 return value.add(1l, TimeUnit.NANOSECONDS);
067 }
068
069 public Duration maximum( Duration value1, Duration value2 ) {
070 if (value1 == null) return value2;
071 if (value2 == null) return value1;
072 return new Duration(Math.max(value1.longValue(), value2.longValue()));
073 }
074
075 public Duration minimum( Duration value1, Duration value2 ) {
076 if (value1 == null) return value2;
077 if (value2 == null) return value1;
078 return new Duration(Math.min(value1.longValue(), value2.longValue()));
079 }
080
081 public int compare( Duration value1, Duration value2 ) {
082 if (value1 == null) return value2 != null ? -1 : 0;
083 if (value2 == null) return 1;
084 return value1.compareTo(value2);
085 }
086
087 public BigDecimal asBigDecimal( Duration value ) {
088 return value != null ? value.toBigDecimal() : null;
089 }
090
091 public Duration fromBigDecimal( BigDecimal value ) {
092 return value != null ? new Duration(value.longValue()) : null;
093 }
094
095 public Duration createZeroValue() {
096 return new Duration(0l);
097 }
098
099 public Duration create( int value ) {
100 return new Duration(value);
101 }
102
103 public Duration create( long value ) {
104 return new Duration(value);
105 }
106
107 public Duration create( double value ) {
108 return new Duration((long)value);
109 }
110
111 public double sqrt( Duration value ) {
112 return Math.sqrt(value.longValue());
113 }
114
115 public Comparator<Duration> getComparator() {
116 return this;
117 }
118
119 public Duration random( Duration minimum, Duration maximum, Random rng ) {
120 Duration difference = subtract(maximum, minimum);
121 return new Duration(minimum.getDuratinInNanoseconds() + rng.nextInt(difference.intValue()));
122 }
123
124 public double doubleValue( Duration value ) {
125 return value.doubleValue();
126 }
127
128 public float floatValue( Duration value ) {
129 return value.floatValue();
130 }
131
132 public int intValue( Duration value ) {
133 return value.intValue();
134 }
135
136 public long longValue( Duration value ) {
137 return value.longValue();
138 }
139
140 public short shortValue( Duration value ) {
141 return value.shortValue();
142 }
143
144 public int getExponentInScientificNotation( Duration value ) {
145 long v = Math.abs(value.getDuratinInNanoseconds());
146 int exp = 0;
147 if (v > 1l) {
148 while (v >= 10l) {
149 v /= 10l;
150 ++exp;
151 }
152 }
153 return exp;
154 }
155
156 public Duration roundUp( Duration durationValue, int decimalShift ) {
157 long value = durationValue.longValue();
158 if (value == 0) return new Duration(0l);
159 if (decimalShift >= 0) return durationValue;
160 long shiftedValueP5 = Math.abs(value);
161 for (int i = 0; i != (-decimalShift - 1); ++i)
162 shiftedValueP5 /= 10l;
163 shiftedValueP5 += 5l;
164 long shiftedValue = shiftedValueP5 / 10l;
165 if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue;
166 shiftedValue *= Long.signum(value);
167 for (int i = 0; i != -decimalShift; ++i)
168 shiftedValue *= 10l;
169 return new Duration(shiftedValue);
170 }
171
172 public Duration roundDown( Duration durationValue, int decimalShift ) {
173 long value = durationValue.longValue();
174 if (value == 0) return new Duration(0l);
175 if (decimalShift >= 0) return durationValue;
176 long shiftedValue = Math.abs(value);
177 for (int i = 0; i != -decimalShift; ++i)
178 shiftedValue /= 10l;
179 shiftedValue *= Long.signum(value);
180 for (int i = 0; i != -decimalShift; ++i)
181 shiftedValue *= 10l;
182 return new Duration(shiftedValue);
183 }
184
185 public Duration keepSignificantFigures( Duration value, int numSigFigs ) {
186 if (numSigFigs < 0) return value;
187 if (numSigFigs == 0) return new Duration(0l);
188 int currentExp = getExponentInScientificNotation(value);
189 int decimalShift = -currentExp + numSigFigs - 1;
190 return roundUp(value, decimalShift);
191 }
192 }