1 package org.djunits.value.vdouble.scalar.base;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.InvocationTargetException;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import org.djunits.unit.AbsoluteLinearUnit;
9 import org.djunits.unit.SIUnit;
10 import org.djunits.unit.Unit;
11 import org.djunits.unit.si.SIPrefixes;
12 import org.djunits.unit.util.UnitRuntimeException;
13 import org.djunits.value.Absolute;
14 import org.djunits.value.base.Scalar;
15 import org.djunits.value.formatter.Format;
16 import org.djunits.value.util.ValueUtil;
17 import org.djunits.value.vdouble.scalar.SIScalar;
18
19
20
21
22
23
24
25
26
27
28
29
30 public abstract class DoubleScalar<U extends Unit<U>, S extends DoubleScalar<U, S>> extends Scalar<U, S>
31 {
32
33 private static final long serialVersionUID = 20161015L;
34
35
36 @SuppressWarnings("checkstyle:visibilitymodifier")
37 public final double si;
38
39
40
41
42
43
44 public DoubleScalar(final U unit, final double si)
45 {
46 super(unit);
47 this.si = si;
48 }
49
50
51
52
53
54 public final double getSI()
55 {
56 return this.si;
57 }
58
59
60
61
62
63 public final double getInUnit()
64 {
65 return ValueUtil.expressAsUnit(getSI(), getDisplayUnit());
66 }
67
68
69
70
71
72
73 public final double getInUnit(final U targetUnit)
74 {
75 return ValueUtil.expressAsUnit(getSI(), targetUnit);
76 }
77
78
79 @Override
80 public final boolean lt(final S o)
81 {
82 return this.getSI() < o.getSI();
83 }
84
85
86 @Override
87 public final boolean le(final S o)
88 {
89 return this.getSI() <= o.getSI();
90 }
91
92
93 @Override
94 public final boolean gt(final S o)
95 {
96 return this.getSI() > o.getSI();
97 }
98
99
100 @Override
101 public final boolean ge(final S o)
102 {
103 return this.getSI() >= o.getSI();
104 }
105
106
107 @Override
108 public final boolean eq(final S o)
109 {
110 return this.getSI() == o.getSI();
111 }
112
113
114 @Override
115 public final boolean ne(final S o)
116 {
117 return this.getSI() != o.getSI();
118 }
119
120
121 @Override
122 public final boolean lt0()
123 {
124 return this.getSI() < 0.0;
125 }
126
127
128 @Override
129 public final boolean le0()
130 {
131 return this.getSI() <= 0.0;
132 }
133
134
135 @Override
136 public final boolean gt0()
137 {
138 return this.getSI() > 0.0;
139 }
140
141
142 @Override
143 public final boolean ge0()
144 {
145 return this.getSI() >= 0.0;
146 }
147
148
149 @Override
150 public final boolean eq0()
151 {
152 return this.getSI() == 0.0;
153 }
154
155
156 @Override
157 public final boolean ne0()
158 {
159 return this.getSI() != 0.0;
160 }
161
162
163 @Override
164 public final int compareTo(final S o)
165 {
166 return Double.compare(this.getSI(), o.getSI());
167 }
168
169
170 @Override
171 public int intValue()
172 {
173 return (int) this.getSI();
174 }
175
176
177 @Override
178 public long longValue()
179 {
180 return (long) this.getSI();
181 }
182
183
184 @Override
185 public float floatValue()
186 {
187 return (float) this.getSI();
188 }
189
190
191 @Override
192 public double doubleValue()
193 {
194 return this.getSI();
195 }
196
197
198
199
200
201
202 @Override
203 public String toString()
204 {
205 return toString(getDisplayUnit(), false, true);
206 }
207
208
209 @Override
210 public String toString(final U displayUnit)
211 {
212 return toString(displayUnit, false, true);
213 }
214
215
216 @Override
217 public String toString(final boolean verbose, final boolean withUnit)
218 {
219 return toString(getDisplayUnit(), verbose, withUnit);
220 }
221
222
223 @Override
224 public String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
225 {
226 StringBuffer buf = new StringBuffer();
227 if (verbose)
228 {
229 buf.append(this instanceof Absolute ? "Abs " : "Rel ");
230 }
231 double d = ValueUtil.expressAsUnit(getSI(), displayUnit);
232 buf.append(Format.format(d));
233 if (withUnit)
234 {
235 buf.append(" ");
236 buf.append(displayUnit.getLocalizedDisplayAbbreviation());
237 }
238 return buf.toString();
239 }
240
241
242
243
244
245
246 public String toStringSIPrefixed()
247 {
248 return toStringSIPrefixed(-24, 26);
249 }
250
251
252
253
254
255
256
257
258 public String toStringSIPrefixed(final int smallestPower, final int biggestPower)
259 {
260
261 if (!Double.isFinite(this.si))
262 {
263 return toString(getDisplayUnit().getStandardUnit());
264 }
265
266
267 String check = String.format(this.si >= 0 ? "%10.8E" : "%10.7E", this.si);
268 int exponent = Integer.parseInt(check.substring(check.indexOf("E") + 1));
269 if (exponent < -24 || exponent < smallestPower || exponent > 24 + 2 || exponent > biggestPower)
270 {
271
272 return String.format(this.si >= 0 ? "%10.4E" : "%10.3E", this.si) + " "
273 + getDisplayUnit().getStandardUnit().getId();
274 }
275 Integer roundedExponent = (int) Math.ceil((exponent - 2.0) / 3) * 3;
276
277 String key =
278 SIPrefixes.FACTORS.get(roundedExponent).getDefaultTextualPrefix() + getDisplayUnit().getStandardUnit().getId();
279 U displayUnit = getDisplayUnit().getQuantity().getUnitByAbbreviation(key);
280 return toString(displayUnit);
281 }
282
283
284 @Override
285 public String toTextualString()
286 {
287 return toTextualString(getDisplayUnit());
288 }
289
290
291 @Override
292 public String toTextualString(final U displayUnit)
293 {
294 double d = ValueUtil.expressAsUnit(getSI(), displayUnit);
295 return format(d) + " " + displayUnit.getLocalizedTextualAbbreviation();
296 }
297
298
299 @Override
300 public String toDisplayString()
301 {
302 return toDisplayString(getDisplayUnit());
303 }
304
305
306 @Override
307 public String toDisplayString(final U displayUnit)
308 {
309 double d = ValueUtil.expressAsUnit(getSI(), displayUnit);
310 return format(d) + " " + displayUnit.getLocalizedDisplayAbbreviation();
311 }
312
313
314 @Override
315 @SuppressWarnings("checkstyle:designforextension")
316 public int hashCode()
317 {
318 final int prime = 31;
319 int result = getDisplayUnit().getStandardUnit().hashCode();
320 long temp;
321 temp = Double.doubleToLongBits(this.getSI());
322 result = prime * result + (int) (temp ^ (temp >>> 32));
323 return result;
324 }
325
326
327 @Override
328 @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces", "unchecked"})
329 public boolean equals(final Object obj)
330 {
331 if (this == obj)
332 return true;
333 if (obj == null)
334 return false;
335 if (getClass() != obj.getClass())
336 return false;
337 DoubleScalar<U, S> other = (DoubleScalar<U, S>) obj;
338 if (!getDisplayUnit().getStandardUnit().equals(other.getDisplayUnit().getStandardUnit()))
339 return false;
340 if (Double.doubleToLongBits(this.getSI()) != Double.doubleToLongBits(other.getSI()))
341 return false;
342 return true;
343 }
344
345
346
347
348
349
350 private static final Map<Unit<?>, Constructor<? extends DoubleScalar<?, ?>>> CACHE = new HashMap<>();
351
352
353
354
355
356
357
358
359
360 public static <U extends Unit<U>, S extends DoubleScalar<U, S>> S instantiate(final double value, final U unit)
361 {
362 return instantiateAnonymous(value, unit);
363 }
364
365
366
367
368
369
370
371
372
373 public static <U extends Unit<U>, S extends DoubleScalar<U, S>> S instantiateSI(final double valueSI,
374 final U displayUnit)
375 {
376 S result = instantiateAnonymous(valueSI, displayUnit.getStandardUnit());
377 result.setDisplayUnit(displayUnit);
378 return result;
379 }
380
381
382
383
384
385
386
387
388
389
390 @SuppressWarnings("unchecked")
391 public static <S extends DoubleScalar<?, S>> S instantiateAnonymous(final double value, final Unit<?> unit)
392 {
393 try
394 {
395 Constructor<? extends DoubleScalar<?, ?>> scalarConstructor = CACHE.get(unit);
396 if (scalarConstructor == null)
397 {
398 if (!unit.getClass().getSimpleName().endsWith("Unit"))
399 {
400 throw new ClassNotFoundException("Unit " + unit.getClass().getSimpleName()
401 + " name does noet end with 'Unit'. Cannot find corresponding scalar");
402 }
403 Class<? extends DoubleScalar<?, ?>> scalarClass;
404 if (unit instanceof SIUnit)
405 {
406 scalarClass = SIScalar.class;
407 }
408 else
409 {
410 scalarClass = (Class<DoubleScalar<?, ?>>) Class
411 .forName("org.djunits.value.vdouble.scalar." + unit.getClass().getSimpleName().replace("Unit", ""));
412 }
413 scalarConstructor = scalarClass.getDeclaredConstructor(double.class, unit.getClass());
414 CACHE.put(unit, scalarConstructor);
415 }
416 return (S) scalarConstructor.newInstance(value, unit);
417 }
418 catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
419 | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
420 {
421 throw new UnitRuntimeException("Cannot instantiate DoubleScalar of unit " + unit.toString() + ". Reason: "
422 + exception.getMessage());
423 }
424 }
425
426
427
428
429
430
431
432
433
434
435
436
437 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
438 R extends DoubleScalarRelWithAbs<AU, A, RU, R>,
439 A extends DoubleScalarAbs<AU, A, RU, R>> A plus(final A left, final R right)
440 {
441 return left.plus(right);
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
456 R extends DoubleScalarRelWithAbs<AU, A, RU, R>,
457 A extends DoubleScalarAbs<AU, A, RU, R>> A plus(final R left, final A right)
458 {
459 return right.plus(left);
460 }
461
462
463
464
465
466
467
468
469
470
471 public static <U extends Unit<U>, R extends DoubleScalarRel<U, R>> R plus(final R left, final R right)
472 {
473 return left.plus(right);
474 }
475
476
477
478
479
480
481
482
483
484
485
486
487 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
488 R extends DoubleScalarRelWithAbs<AU, A, RU, R>,
489 A extends DoubleScalarAbs<AU, A, RU, R>> A minus(final A left, final R right)
490 {
491 return left.minus(right);
492 }
493
494
495
496
497
498
499
500
501
502
503 public static <U extends Unit<U>, R extends DoubleScalarRel<U, R>> R minus(final R left, final R right)
504 {
505 return left.minus(right);
506 }
507
508
509
510
511
512
513
514
515
516
517
518
519 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
520 R extends DoubleScalarRelWithAbs<AU, A, RU, R>,
521 A extends DoubleScalarAbs<AU, A, RU, R>> R minus(final A left, final A right)
522 {
523 return left.minus(right);
524 }
525
526
527
528
529
530
531
532 public static SIScalar multiply(final DoubleScalarRel<?, ?> left, final DoubleScalarRel<?, ?> right)
533 {
534 SIUnit targetUnit = Unit.lookupOrCreateUnitWithSIDimensions(left.getDisplayUnit().getQuantity().getSiDimensions()
535 .plus(right.getDisplayUnit().getQuantity().getSiDimensions()));
536 return new SIScalar(left.getSI() * right.getSI(), targetUnit);
537 }
538
539
540
541
542
543
544
545 public static SIScalar divide(final DoubleScalarRel<?, ?> left, final DoubleScalarRel<?, ?> right)
546 {
547 SIUnit targetUnit = Unit.lookupOrCreateUnitWithSIDimensions(left.getDisplayUnit().getQuantity().getSiDimensions()
548 .minus(right.getDisplayUnit().getQuantity().getSiDimensions()));
549 return new SIScalar(left.getSI() / right.getSI(), targetUnit);
550 }
551
552
553
554
555
556
557
558
559
560
561 public static <U extends Unit<U>, R extends DoubleScalarRel<U, R>> R interpolate(final R zero, final R one,
562 final double ratio)
563 {
564 return zero.instantiateRel(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getDisplayUnit()) * ratio,
565 zero.getDisplayUnit());
566 }
567
568
569
570
571
572
573
574
575
576
577
578
579 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
580 R extends DoubleScalarRelWithAbs<AU, A, RU, R>,
581 A extends DoubleScalarAbs<AU, A, RU, R>> A interpolate(final A zero, final A one, final double ratio)
582 {
583 return zero.instantiateAbs(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getDisplayUnit()) * ratio,
584 zero.getDisplayUnit());
585 }
586
587
588
589
590
591
592
593
594
595 public static <U extends Unit<U>, T extends DoubleScalar<U, T>> T max(final T r1, final T r2)
596 {
597 return (r1.gt(r2)) ? r1 : r2;
598 }
599
600
601
602
603
604
605
606
607
608
609 @SafeVarargs
610 public static <U extends Unit<U>, T extends DoubleScalar<U, T>> T max(final T r1, final T r2, final T... rn)
611 {
612 T maxr = (r1.gt(r2)) ? r1 : r2;
613 for (T r : rn)
614 {
615 if (r.gt(maxr))
616 {
617 maxr = r;
618 }
619 }
620 return maxr;
621 }
622
623
624
625
626
627
628
629
630
631 public static <U extends Unit<U>, T extends DoubleScalar<U, T>> T min(final T r1, final T r2)
632 {
633 return r1.lt(r2) ? r1 : r2;
634 }
635
636
637
638
639
640
641
642
643
644
645 @SafeVarargs
646 public static <U extends Unit<U>, T extends DoubleScalar<U, T>> T min(final T r1, final T r2, final T... rn)
647 {
648 T minr = r1.lt(r2) ? r1 : r2;
649 for (T r : rn)
650 {
651 if (r.lt(minr))
652 {
653 minr = r;
654 }
655 }
656 return minr;
657 }
658
659 }