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