75e4b0a8d5a4e9ae4901e0e618ca6274f79a60e2
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Michael Jeanson and others
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.common
.core
.format
;
12 import java
.math
.BigDecimal
;
13 import java
.text
.DecimalFormat
;
14 import java
.text
.FieldPosition
;
15 import java
.text
.Format
;
16 import java
.text
.NumberFormat
;
17 import java
.text
.ParsePosition
;
20 import com
.google
.common
.collect
.ImmutableMap
;
23 * Provides a formatter for decimal numbers with International System of Units
24 * prefixes up to peta (quadrillion). It receives a number and formats it in the
25 * closest thousand's unit, with at most 1 decimal.
27 * @author Michael Jeanson
30 public class DecimalUnitFormat
extends Format
{
32 private static final long serialVersionUID
= 3650332020346870384L;
34 /* International System of Units prefixes */
35 private static final String KILO_PREFIX
= "k"; //$NON-NLS-1$
36 private static final String MEGA_PREFIX
= "M"; //$NON-NLS-1$
37 private static final String GIGA_PREFIX
= "G"; //$NON-NLS-1$
38 private static final String TERA_PREFIX
= "T"; //$NON-NLS-1$
39 private static final String PETA_PREFIX
= "P"; //$NON-NLS-1$
41 private static final String MILLI_PREFIX
= "m"; //$NON-NLS-1$
42 private static final String MICRO_PREFIX
= "ยต"; //$NON-NLS-1$
43 private static final String NANO_PREFIX
= "n"; //$NON-NLS-1$
44 private static final String PICO_PREFIX
= "p"; //$NON-NLS-1$
46 private static final long KILO
= 1000L;
47 private static final long MEGA
= 1000000L;
48 private static final long GIGA
= 1000000000L;
49 private static final long TERA
= 1000000000000L;
50 private static final long PETA
= 1000000000000000L;
52 private static final double MILLI
= 0.001;
53 private static final double MICRO
= 0.000001;
54 private static final double NANO
= 0.000000001;
55 private static final double PICO
= 0.000000000001;
57 /* Map of prefix to exponent */
58 private static final Map
<String
, Integer
> PREFIX_MAP
= ImmutableMap
.<String
, Integer
>builder()
62 .put(TERA_PREFIX
, +12)
63 .put(PETA_PREFIX
, +15)
64 .put(MILLI_PREFIX
, -3)
65 .put(MICRO_PREFIX
, -6)
67 .put(PICO_PREFIX
, -12)
69 private static final Format FORMAT
= new DecimalFormat("#.#"); //$NON-NLS-1$
70 private final double fFactor
;
74 * Default constructor.
76 public DecimalUnitFormat() {
82 * Constructor with multiplication factor.
84 * @param factor Multiplication factor to apply to the value
86 public DecimalUnitFormat(double factor
) {
92 public StringBuffer
format(Object obj
, StringBuffer toAppendTo
, FieldPosition pos
) {
93 if (obj
instanceof Number
) {
94 Number num
= (Number
) obj
;
96 /* Apply the multiplication factor before formatting */
97 double value
= num
.doubleValue() * fFactor
;
99 double abs
= Math
.abs(value
);
101 if (Double
.isInfinite(value
) || Double
.isNaN(value
) || abs
< PICO
) {
102 return toAppendTo
.append(FORMAT
.format(value
));
106 if (abs
> Long
.MAX_VALUE
) {
107 return toAppendTo
.append(num
);
110 return toAppendTo
.append(FORMAT
.format(value
/ PETA
)).append(' ').append(PETA_PREFIX
);
113 return toAppendTo
.append(FORMAT
.format(value
/ TERA
)).append(' ').append(TERA_PREFIX
);
116 return toAppendTo
.append(FORMAT
.format(value
/ GIGA
)).append(' ').append(GIGA_PREFIX
);
119 return toAppendTo
.append(FORMAT
.format(value
/ MEGA
)).append(' ').append(MEGA_PREFIX
);
122 return toAppendTo
.append(FORMAT
.format(value
/ KILO
)).append(' ').append(KILO_PREFIX
);
125 return toAppendTo
.append(FORMAT
.format(value
));
129 return toAppendTo
.append(FORMAT
.format(value
* TERA
)).append(' ').append(PICO_PREFIX
);
132 return toAppendTo
.append(FORMAT
.format(value
* GIGA
)).append(' ').append(NANO_PREFIX
);
135 return toAppendTo
.append(FORMAT
.format(value
* MEGA
)).append(' ').append(MICRO_PREFIX
);
138 return toAppendTo
.append(FORMAT
.format(value
* KILO
)).append(' ').append(MILLI_PREFIX
);
141 throw new IllegalArgumentException("Cannot format given Object as a Number: " + obj
); //$NON-NLS-1$
148 public Number
parseObject(String source
, ParsePosition pos
) {
149 Number number
= NumberFormat
.getInstance().parse(source
, pos
);
150 if (number
== null) {
153 String unit
= source
.substring(pos
.getIndex()).trim();
154 Integer exponent
= null;
155 if (!unit
.isEmpty()) {
156 String prefix
= unit
.substring(0, 1);
157 exponent
= PREFIX_MAP
.get(prefix
);
159 if (exponent
!= null && Double
.isFinite(number
.doubleValue())) {
160 BigDecimal bd
= new BigDecimal(number
.toString());
161 bd
= bd
.movePointRight(exponent
.intValue());
162 if (bd
.remainder(BigDecimal
.ONE
).equals(BigDecimal
.ZERO
) &&
163 bd
.abs().compareTo(new BigDecimal(Long
.MAX_VALUE
)) < 0) {
164 return bd
.longValue();
166 return bd
.doubleValue();
This page took 0.033018 seconds and 4 git commands to generate.