Logo

Programming-Idioms

This language bar is your friend. Select your favorite languages!

Idiom #364 Calculate the order of magnitude for a value

Calculate the `SI prefix`, s, of value a.

For example, `k, M, G, T, etc.`

https://en.wikipedia.org/wiki/Metric_prefix
https://en.wikipedia.org/wiki/Orders_of_magnitude_(bit_rate)

#include <cmath>
#include <vector>
using namespace std;
struct units {
    double y;
    vector<char> a;
    units(int x) { y = log(x); }
    void add(char x) { a.push_back(x); }
    pair<int, char> get(int x) {
        int i (log(x) / y);
        return {i, a[i - 1]};
    }
};
units u {1'000};
for (char x : "kMGT") u.add(x);
pair p {u.get(a)};
a /= pow(1'000, p.first);
char x {p.second};
#include <cmath>
int y (log(a) / log(1'000));
a /= pow(1'000, y);
char x {"kMGT"[y - 1]};
import static java.lang.Math.log;
import static java.lang.Math.pow;
enum SI {
    k("kilo"),
    M("mega"),
    G("giga"),
    T("tera");
    String s;
    static double y = log(1_000);
    SI(String s) { this.s = s; }
    static SI get(double x) {
        int y = (int) (log(x) / SI.y);
        return values()[y - 1];
    }
}
SI si = SI.get(a);
a /= pow(1_000, si.ordinal() + 1);
String x = si.name();
import static java.lang.Math.log;
import static java.lang.Math.pow;
int y = (int) (log(a) / log(1_000));
a /= pow(1_000, y);
char x = "kMGT".charAt(y - 1);
function GetSIPrefix(AValue: Double): string;
const
  SIPrefixes: array[1..24] of String = ('Q','R','Y', 'Z','E','P','T','G','M','K','H','D','','d','c','m','µ','mc','n','p','f','a','z','y');
  SIFactors:  array[1..24] of Double = (1E+30,1E+27,1E+24, 1E+21, 1E+18, 1E+15, 1E+12, 1E+9, 1E+6, 1E+3,1E+2,1E+1,1,1E-1,1E-2,
var
  i: Integer;
begin
  Result := '';
  for i := 1 to 24 do
  begin
    if (Abs(AValue) >= SIFactors[i]) then
    begin
      Exit(SIPrefixes[i]);
    end;
  end;
end;
from itertools import count
from math import log
class System(dict):
    k = 'kilo'
    M = 'mega'
    G = 'giga'
    T = 'tera'
    def __init__(self):
        super().__init__()
        m = vars(System)
        i = count(1)
        f = lambda k: k[0] != '_'
        for key in filter(f, m):
            k = next(i) * 3
            v = m[key], 10 ** k
            self[k] = key, *v
system = System()
key = int(log(a, 1_000)) * 3
s, text, factor = system[key]
string = f'{a / factor} {s}B'
from math import log
λ = int(log(a, 1_000))
a /= 1_000 ** λ
s = 'kMGT'[λ - 1]
from math import log
def parse(value, array, base=10):
    m = lambda _, x: int.__new__(_, x)
    n = lambda _: _.__class__.__name__
    d = {'__new__': m, '__str__': n}
    λ = int(log(value, base))
    T = type(array[λ - 1], (int,), d)
    return T(base ** λ)
unit = parse(a, 'kMGT', 1_000)
string = f'{a / unit} {unit}B'
from math import log
class Units(list):
    def __init__(self, s, base):
        super().__init__()
        self.base = base
        m = lambda _, x: int.__new__(_, x)
        n = lambda _: _.__class__.__name__
        d = {'__new__': m, '__str__': n}
        for y, x in enumerate(s, 1):
            x = type(x, (int,), d)
            self.append(x(base ** y))
    def parse(self, x):
        y = int(log(x, self.base))
        return self[y - 1]
u = Units('kMGT', 1_000)
u = u.parse(a)
s = f'{a / u} {u}B'
x =  case a
  when 1e3... 1e6 ; "k"
  when 1e6... 1e9 ; "M"
  when 1e9... 1e12; "G"
  when 1e12...1e15; "T"
  else ""
end

New implementation...
< >
reilas