1 package org.djunits.value.vfloat.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.vfloat.scalar.FloatSIScalar;
18
19
20
21
22
23
24
25
26
27
28
29
30 public abstract class FloatScalar<U extends Unit<U>, S extends FloatScalar<U, S>> extends Scalar<U, S>
31 {
32
33 private static final long serialVersionUID = 20161015L;
34
35
36 @SuppressWarnings("checkstyle:visibilitymodifier")
37 public final float si;
38
39
40
41
42
43
44 public FloatScalar(final U unit, final float si)
45 {
46 super(unit);
47 this.si = si;
48 }
49
50
51
52
53
54 public final float getSI()
55 {
56 return this.si;
57 }
58
59
60
61
62
63 public final float getInUnit()
64 {
65 return (float) ValueUtil.expressAsUnit(getSI(), getDisplayUnit());
66 }
67
68
69
70
71
72
73 public final float getInUnit(final U targetUnit)
74 {
75 return (float) 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 Float.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 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 float d = (float) 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 float f = (float) ValueUtil.expressAsUnit(getSI(), displayUnit);
295 return format(f) + " " + 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 float f = (float) ValueUtil.expressAsUnit(getSI(), displayUnit);
310 return format(f) + " " + 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 = Float.floatToIntBits(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 FloatScalar<U, S> other = (FloatScalar<U, S>) obj;
338 if (!getDisplayUnit().getStandardUnit().equals(other.getDisplayUnit().getStandardUnit()))
339 return false;
340 if (Float.floatToIntBits(this.getSI()) != Float.floatToIntBits(other.getSI()))
341 return false;
342 return true;
343 }
344
345
346
347
348
349
350 private static final Map<Unit<?>, Constructor<? extends FloatScalar<?, ?>>> CACHE = new HashMap<>();
351
352
353
354
355
356
357
358
359
360 public static <U extends Unit<U>, S extends FloatScalar<U, S>> S instantiate(final float 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 FloatScalar<U, S>> S instantiateSI(final float valueSI, final U displayUnit)
374 {
375 S result = instantiateAnonymous(valueSI, displayUnit.getStandardUnit());
376 result.setDisplayUnit(displayUnit);
377 return result;
378 }
379
380
381
382
383
384
385
386
387
388
389 @SuppressWarnings("unchecked")
390 public static <S extends FloatScalar<?, S>> S instantiateAnonymous(final float value, final Unit<?> unit)
391 {
392 try
393 {
394 Constructor<? extends FloatScalar<?, ?>> scalarConstructor = CACHE.get(unit);
395 if (scalarConstructor == null)
396 {
397 if (!unit.getClass().getSimpleName().endsWith("Unit"))
398 {
399 throw new ClassNotFoundException("Unit " + unit.getClass().getSimpleName()
400 + " name does noet end with 'Unit'. Cannot find corresponding scalar");
401 }
402 Class<? extends FloatScalar<?, ?>> scalarClass;
403 if (unit instanceof SIUnit)
404 {
405 scalarClass = FloatSIScalar.class;
406 }
407 else
408 {
409 scalarClass = (Class<FloatScalar<?, ?>>) Class.forName(
410 "org.djunits.value.vfloat.scalar.Float" + unit.getClass().getSimpleName().replace("Unit", ""));
411 }
412 scalarConstructor = scalarClass.getDeclaredConstructor(float.class, unit.getClass());
413 CACHE.put(unit, scalarConstructor);
414 }
415 return (S) scalarConstructor.newInstance(value, unit);
416 }
417 catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
418 | IllegalAccessException | IllegalArgumentException | InvocationTargetException exception)
419 {
420 throw new UnitRuntimeException(
421 "Cannot instantiate FloatScalar of unit " + unit.toString() + ". Reason: " + exception.getMessage());
422 }
423 }
424
425
426
427
428
429
430
431
432
433
434
435
436 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
437 R extends FloatScalarRelWithAbs<AU, A, RU, R>,
438 A extends FloatScalarAbs<AU, A, RU, R>> A plus(final A left, final R right)
439 {
440 return left.plus(right);
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
455 R extends FloatScalarRelWithAbs<AU, A, RU, R>,
456 A extends FloatScalarAbs<AU, A, RU, R>> A plus(final R left, final A right)
457 {
458 return right.plus(left);
459 }
460
461
462
463
464
465
466
467
468
469
470 public static <U extends Unit<U>, R extends FloatScalarRel<U, R>> R plus(final R left, final R right)
471 {
472 return left.plus(right);
473 }
474
475
476
477
478
479
480
481
482
483
484
485
486 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
487 R extends FloatScalarRelWithAbs<AU, A, RU, R>,
488 A extends FloatScalarAbs<AU, A, RU, R>> A minus(final A left, final R right)
489 {
490 return left.minus(right);
491 }
492
493
494
495
496
497
498
499
500
501
502 public static <U extends Unit<U>, R extends FloatScalarRel<U, R>> R minus(final R left, final R right)
503 {
504 return left.minus(right);
505 }
506
507
508
509
510
511
512
513
514
515
516
517
518 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
519 R extends FloatScalarRelWithAbs<AU, A, RU, R>,
520 A extends FloatScalarAbs<AU, A, RU, R>> R minus(final A left, final A right)
521 {
522 return left.minus(right);
523 }
524
525
526
527
528
529
530
531 public static FloatSIScalar multiply(final FloatScalarRel<?, ?> left, final FloatScalarRel<?, ?> right)
532 {
533 SIUnit targetUnit = Unit.lookupOrCreateUnitWithSIDimensions(left.getDisplayUnit().getQuantity().getSiDimensions()
534 .plus(right.getDisplayUnit().getQuantity().getSiDimensions()));
535 return new FloatSIScalar(left.getSI() * right.getSI(), targetUnit);
536 }
537
538
539
540
541
542
543
544 public static FloatSIScalar divide(final FloatScalarRel<?, ?> left, final FloatScalarRel<?, ?> right)
545 {
546 SIUnit targetUnit = Unit.lookupOrCreateUnitWithSIDimensions(left.getDisplayUnit().getQuantity().getSiDimensions()
547 .minus(right.getDisplayUnit().getQuantity().getSiDimensions()));
548 return new FloatSIScalar(left.getSI() / right.getSI(), targetUnit);
549 }
550
551
552
553
554
555
556
557
558
559
560 public static <U extends Unit<U>, R extends FloatScalarRel<U, R>> R interpolate(final R zero, final R one,
561 final float ratio)
562 {
563 return zero.instantiateRel(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getDisplayUnit()) * ratio,
564 zero.getDisplayUnit());
565 }
566
567
568
569
570
571
572
573
574
575
576
577
578 public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>,
579 R extends FloatScalarRelWithAbs<AU, A, RU, R>,
580 A extends FloatScalarAbs<AU, A, RU, R>> A interpolate(final A zero, final A one, final float ratio)
581 {
582 return zero.instantiateAbs(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getDisplayUnit()) * ratio,
583 zero.getDisplayUnit());
584 }
585
586
587
588
589
590
591
592
593
594 public static <U extends Unit<U>, T extends FloatScalar<U, T>> T max(final T r1, final T r2)
595 {
596 return (r1.gt(r2)) ? r1 : r2;
597 }
598
599
600
601
602
603
604
605
606
607
608 @SafeVarargs
609 public static <U extends Unit<U>, T extends FloatScalar<U, T>> T max(final T r1, final T r2, final T... rn)
610 {
611 T maxr = (r1.gt(r2)) ? r1 : r2;
612 for (T r : rn)
613 {
614 if (r.gt(maxr))
615 {
616 maxr = r;
617 }
618 }
619 return maxr;
620 }
621
622
623
624
625
626
627
628
629
630 public static <U extends Unit<U>, T extends FloatScalar<U, T>> T min(final T r1, final T r2)
631 {
632 return r1.lt(r2) ? r1 : r2;
633 }
634
635
636
637
638
639
640
641
642
643
644 @SafeVarargs
645 public static <U extends Unit<U>, T extends FloatScalar<U, T>> T min(final T r1, final T r2, final T... rn)
646 {
647 T minr = r1.lt(r2) ? r1 : r2;
648 for (T r : rn)
649 {
650 if (r.lt(minr))
651 {
652 minr = r;
653 }
654 }
655 return minr;
656 }
657
658 }