1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.modeshape.common.math;
25
26 import java.math.BigDecimal;
27 import java.util.Comparator;
28 import java.util.Random;
29 import java.util.concurrent.TimeUnit;
30 import net.jcip.annotations.Immutable;
31
32
33
34
35 @Immutable
36 public class DurationOperations implements MathOperations<Duration>, Comparator<Duration> {
37
38 public Class<Duration> getOperandClass() {
39 return Duration.class;
40 }
41
42 public Duration add( Duration value1,
43 Duration value2 ) {
44 if (value1 == null) return value2 != null ? value2 : createZeroValue();
45 if (value2 == null) return value1;
46 return value1.add(value2);
47 }
48
49 public Duration subtract( Duration value1,
50 Duration value2 ) {
51 if (value1 == null) return negate(value2);
52 if (value2 == null) return value1;
53 return value1.subtract(value2);
54 }
55
56 public Duration multiply( Duration value1,
57 Duration value2 ) {
58 if (value1 == null || value2 == null) return createZeroValue();
59 return value1.multiply(value2.longValue());
60 }
61
62 public double divide( Duration value1,
63 Duration value2 ) {
64 if (value1 == null || value2 == null) throw new IllegalArgumentException();
65 return value1.divide(value2);
66 }
67
68 public Duration negate( Duration value ) {
69 if (value == null) return createZeroValue();
70 return value.multiply(value.longValue() * -1);
71 }
72
73 public Duration increment( Duration value ) {
74 if (value == null) return createZeroValue();
75 return value.add(1l, TimeUnit.NANOSECONDS);
76 }
77
78 public Duration maximum( Duration value1,
79 Duration value2 ) {
80 if (value1 == null) return value2;
81 if (value2 == null) return value1;
82 return new Duration(Math.max(value1.longValue(), value2.longValue()));
83 }
84
85 public Duration minimum( Duration value1,
86 Duration value2 ) {
87 if (value1 == null) return value2;
88 if (value2 == null) return value1;
89 return new Duration(Math.min(value1.longValue(), value2.longValue()));
90 }
91
92 public int compare( Duration value1,
93 Duration value2 ) {
94 if (value1 == null) return value2 != null ? -1 : 0;
95 if (value2 == null) return 1;
96 return value1.compareTo(value2);
97 }
98
99 public BigDecimal asBigDecimal( Duration value ) {
100 return value != null ? value.toBigDecimal() : null;
101 }
102
103 public Duration fromBigDecimal( BigDecimal value ) {
104 return value != null ? new Duration(value.longValue()) : null;
105 }
106
107 public Duration createZeroValue() {
108 return new Duration(0l);
109 }
110
111 public Duration create( int value ) {
112 return new Duration(value);
113 }
114
115 public Duration create( long value ) {
116 return new Duration(value);
117 }
118
119 public Duration create( double value ) {
120 return new Duration((long)value);
121 }
122
123 public double sqrt( Duration value ) {
124 return Math.sqrt(value.longValue());
125 }
126
127 public Comparator<Duration> getComparator() {
128 return this;
129 }
130
131 public Duration random( Duration minimum,
132 Duration maximum,
133 Random rng ) {
134 Duration difference = subtract(maximum, minimum);
135 return new Duration(minimum.getDuratinInNanoseconds() + rng.nextInt(difference.intValue()));
136 }
137
138 public double doubleValue( Duration value ) {
139 return value.doubleValue();
140 }
141
142 public float floatValue( Duration value ) {
143 return value.floatValue();
144 }
145
146 public int intValue( Duration value ) {
147 return value.intValue();
148 }
149
150 public long longValue( Duration value ) {
151 return value.longValue();
152 }
153
154 public short shortValue( Duration value ) {
155 return value.shortValue();
156 }
157
158 public int getExponentInScientificNotation( Duration value ) {
159 long v = Math.abs(value.getDuratinInNanoseconds());
160 int exp = 0;
161 if (v > 1l) {
162 while (v >= 10l) {
163 v /= 10l;
164 ++exp;
165 }
166 }
167 return exp;
168 }
169
170 public Duration roundUp( Duration durationValue,
171 int decimalShift ) {
172 long value = durationValue.longValue();
173 if (value == 0) return new Duration(0l);
174 if (decimalShift >= 0) return durationValue;
175 long shiftedValueP5 = Math.abs(value);
176 for (int i = 0; i != (-decimalShift - 1); ++i)
177 shiftedValueP5 /= 10l;
178 shiftedValueP5 += 5l;
179 long shiftedValue = shiftedValueP5 / 10l;
180 if (shiftedValue * 10l - shiftedValueP5 >= 5) ++shiftedValue;
181 shiftedValue *= Long.signum(value);
182 for (int i = 0; i != -decimalShift; ++i)
183 shiftedValue *= 10l;
184 return new Duration(shiftedValue);
185 }
186
187 public Duration roundDown( Duration durationValue,
188 int decimalShift ) {
189 long value = durationValue.longValue();
190 if (value == 0) return new Duration(0l);
191 if (decimalShift >= 0) return durationValue;
192 long shiftedValue = Math.abs(value);
193 for (int i = 0; i != -decimalShift; ++i)
194 shiftedValue /= 10l;
195 shiftedValue *= Long.signum(value);
196 for (int i = 0; i != -decimalShift; ++i)
197 shiftedValue *= 10l;
198 return new Duration(shiftedValue);
199 }
200
201 public Duration keepSignificantFigures( Duration value,
202 int numSigFigs ) {
203 if (numSigFigs < 0) return value;
204 if (numSigFigs == 0) return new Duration(0l);
205 int currentExp = getExponentInScientificNotation(value);
206 int decimalShift = -currentExp + numSigFigs - 1;
207 return roundUp(value, decimalShift);
208 }
209 }