Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically format a measurement into engineering units in Java

I'm trying to find a way to automatically format a measurement and unit into a String in engineering notation. This is a special case of scientific notation, in that the exponent is always a multiple of three, but is denoted using kilo, mega, milli, micro prefixes.

This would be similar to this post except it should handle the whole range of SI units and prefixes.

For example, I'm after a library that will format quantities such that: 12345.6789 Hz would be formatted as 12 kHz or 12.346 kHz or 12.3456789 kHz 1234567.89 J would be formatted as 1 MJ or 1.23 MJ or 1.2345 MJ And so on.

JSR-275 / JScience handle the unit measurement ok, but I'm yet to find something that will work out the most appropriate scaling prefix automatically based on the magnitude of the measurement.

Cheers, Sam.

like image 785
SamWest Avatar asked Oct 12 '22 16:10

SamWest


1 Answers

import java.util.*;
class Measurement {
    public static final Map<Integer,String> prefixes;
    static {
        Map<Integer,String> tempPrefixes = new HashMap<Integer,String>();
        tempPrefixes.put(0,"");
        tempPrefixes.put(3,"k");
        tempPrefixes.put(6,"M");
        tempPrefixes.put(9,"G");
        tempPrefixes.put(12,"T");
        tempPrefixes.put(-3,"m");
        tempPrefixes.put(-6,"u");
        prefixes = Collections.unmodifiableMap(tempPrefixes);
    }

    String type;
    double value;

    public Measurement(double value, String type) {
        this.value = value;
        this.type = type;
    }

    public String toString() {
        double tval = value;
        int order = 0;
        while(tval > 1000.0) {
            tval /= 1000.0;
            order += 3;
        }
        while(tval < 1.0) {
            tval *= 1000.0;
            order -= 3;
        }
        return tval + prefixes.get(order) + type;
    }

    public static void main(String[] args) {
        Measurement dist = new Measurement(1337,"m"); // should be 1.337Km
        Measurement freq = new Measurement(12345678,"hz"); // should be 12.3Mhz
        Measurement tiny = new Measurement(0.00034,"m"); // should be 0.34mm

        System.out.println(dist);
        System.out.println(freq);
        System.out.println(tiny);

    }

}
like image 71
corsiKa Avatar answered Oct 14 '22 08:10

corsiKa