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