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 net.jcip.annotations.Immutable;
30
31
32
33
34 @Immutable
35 public class DoubleOperations implements MathOperations<Double>, Comparator<Double> {
36
37 public Class<Double> getOperandClass() {
38 return Double.class;
39 }
40
41 public Double add( Double value1,
42 Double value2 ) {
43 if (value1 == null) return value2 != null ? value2 : createZeroValue();
44 if (value2 == null) return value1;
45 return (value1 + value2);
46 }
47
48 public Double subtract( Double value1,
49 Double value2 ) {
50 if (value1 == null) return negate(value2);
51 if (value2 == null) return value1;
52 return (value1 - value2);
53 }
54
55 public Double multiply( Double value1,
56 Double value2 ) {
57 if (value1 == null || value2 == null) return createZeroValue();
58 return (value1 * value2);
59 }
60
61 public double divide( Double value1,
62 Double value2 ) {
63 if (value1 == null || value2 == null) throw new IllegalArgumentException();
64 return value1 / value2;
65 }
66
67 public Double negate( Double value ) {
68 if (value == null) return createZeroValue();
69 return (value * -1);
70 }
71
72 public Double increment( Double value ) {
73 if (value == null) return createZeroValue();
74 return (value + 1);
75 }
76
77 public Double maximum( Double value1,
78 Double value2 ) {
79 if (value1 == null) return value2;
80 if (value2 == null) return value1;
81 return Math.max(value1, value2);
82 }
83
84 public Double minimum( Double value1,
85 Double value2 ) {
86 if (value1 == null) return value2;
87 if (value2 == null) return value1;
88 return Math.min(value1, value2);
89 }
90
91 public int compare( Double value1,
92 Double value2 ) {
93 if (value1 == null) return value2 != null ? -1 : 0;
94 if (value2 == null) return 1;
95 return value1.compareTo(value2);
96 }
97
98 public BigDecimal asBigDecimal( Double value ) {
99 return value != null ? new BigDecimal(value) : null;
100 }
101
102 public Double fromBigDecimal( BigDecimal value ) {
103 return value != null ? value.doubleValue() : null;
104 }
105
106 public Double createZeroValue() {
107 return 0.0d;
108 }
109
110 public Double create( int value ) {
111 return (double)value;
112 }
113
114 public Double create( long value ) {
115 return (double)value;
116 }
117
118 public Double create( double value ) {
119 return value;
120 }
121
122 public double sqrt( Double value ) {
123 return Math.sqrt(value);
124 }
125
126 public Comparator<Double> getComparator() {
127 return this;
128 }
129
130 public Double random( Double minimum,
131 Double maximum,
132 Random rng ) {
133 Double difference = subtract(maximum, minimum);
134 return minimum + difference.doubleValue() * rng.nextDouble();
135 }
136
137 public double doubleValue( Double value ) {
138 return value.doubleValue();
139 }
140
141 public float floatValue( Double value ) {
142 return value.floatValue();
143 }
144
145 public int intValue( Double value ) {
146 return value.intValue();
147 }
148
149 public long longValue( Double value ) {
150 return value.longValue();
151 }
152
153 public short shortValue( Double value ) {
154 return value.shortValue();
155 }
156
157 public int getExponentInScientificNotation( Double value ) {
158 double v = Math.abs(value);
159 int exp = 0;
160 if (v > 1.0d) {
161 while (v >= 10.0d) {
162 v /= 10.0d;
163 ++exp;
164 }
165 } else if (v == 0.0d) {
166 } else if (v < 1.0d) {
167 while (v < 1.0d) {
168 v *= 10.0d;
169 --exp;
170 }
171 }
172 return exp;
173 }
174
175 public Double roundUp( Double value,
176 int decimalShift ) {
177 if (value == 0) return 0.0d;
178 double shiftedValue = (Math.abs(value) * Math.pow(10.0d, decimalShift) + 0.5d) * Math.signum(value);
179 double roundedValue = (int)shiftedValue;
180 return roundedValue * Math.pow(10.0d, -decimalShift);
181 }
182
183 public Double roundDown( Double value,
184 int decimalShift ) {
185 if (value == 0) return 0.0d;
186 double shiftedValue = (Math.abs(value) * Math.pow(10.0d, decimalShift)) * Math.signum(value);
187 double roundedValue = (int)shiftedValue;
188 return roundedValue * Math.pow(10.0d, -decimalShift);
189 }
190
191 public Double keepSignificantFigures( Double value,
192 int numSigFigs ) {
193 if (numSigFigs < 0) return value;
194 if (numSigFigs == 0) return 0.0d;
195 int currentExp = getExponentInScientificNotation(value);
196 int decimalShift = -currentExp + numSigFigs - 1;
197 return roundUp(value, decimalShift);
198 }
199 }