/*
PIP - Platform Independent Primitives
Unit prefix
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
*/
#include "piunits_prefix.h"
#include "piliterals_string.h"
#include "pimathbase.h"
#include "pitranslator.h"
#include "piunits_base.h"
// quetta Q 10^30 1000000000000000000000000000000
// ronna R 10^27 1000000000000000000000000000
// yotta Y 10^24 1000000000000000000000000
// zetta Z 10^21 1000000000000000000000
// exa E 10^18 1000000000000000000
// peta P 10^15 1000000000000000
// tera T 10^12 1000000000000
// giga G 10^9 1000000000
// mega M 10^6 1000000
// kilo k 10^3 1000
// hecto h 10^2 100
// deca da 10^1 10
// — — 100 1 —
// deci d 10^−1 0.1
// centi c 10^−2 0.01
// milli m 10^−3 0.001
// micro μ 10^−6 0.000001
// nano n 10^−9 0.000000001
// pico p 10^−12 0.000000000001
// femto f 10^−15 0.000000000000001
// atto a 10^−18 0.000000000000000001
// zepto z 10^−21 0.000000000000000000001
// yocto y 10^−24 0.000000000000000000000001
// ronto r 10^−27 0.000000000000000000000000001
PIString PIUnits::Prefix::name(int prefix) {
return instance().getPrefix(prefix).name;
}
PIString PIUnits::Prefix::prefix(int prefix) {
return instance().getPrefix(prefix).prefix;
}
PIString PIUnits::Prefix::valueToString(double v, void * type_class, int type, char format, int prec) {
auto * tc = reinterpret_cast(type_class);
auto p =
instance().getPrefixForValue(v, tc->supportPrefixesNon3(type), tc->supportPrefixesGreater(type), tc->supportPrefixesSmaller(type));
return PIString::fromNumber(v / p.divider, format, prec) + " "_a + p.prefix;
}
double PIUnits::Prefix::multiplier(int prefix) {
return instance().getPrefix(prefix).divider;
}
PIUnits::Prefix::Prefix() {
def_prefix = {"", "", 0, 1., false};
// clang-format off
prefixes = {
{Deca, {"deca"_tr ("PIUnits"), "da"_tr("PIUnits") , 1 , pow10(1. ), true }},
{Hecto, {"hecto"_tr ("PIUnits"), "h"_tr ("PIUnits") , 2 , pow10(2. ), true }},
{Kilo, {"kilo"_tr ("PIUnits"), "k"_tr ("PIUnits") , 3 , pow10(3. ), false}},
{Mega, {"mega"_tr ("PIUnits"), "M"_tr ("PIUnits") , 6 , pow10(6. ), false}},
{Giga, {"giga"_tr ("PIUnits"), "G"_tr ("PIUnits") , 9 , pow10(9. ), false}},
{Tera, {"tera"_tr ("PIUnits"), "T"_tr ("PIUnits") , 12 , pow10(12. ), false}},
{Peta, {"peta"_tr ("PIUnits"), "P"_tr ("PIUnits") , 15 , pow10(15. ), false}},
{Exa, {"exa"_tr ("PIUnits"), "E"_tr ("PIUnits") , 18 , pow10(18. ), false}},
{Zetta, {"zetta"_tr ("PIUnits"), "Z"_tr ("PIUnits") , 21 , pow10(21. ), false}},
{Yotta, {"yotta"_tr ("PIUnits"), "Y"_tr ("PIUnits") , 24 , pow10(24. ), false}},
{Ronna, {"ronna"_tr ("PIUnits"), "R"_tr ("PIUnits") , 27 , pow10(27. ), false}},
{Quetta, {"quetta"_tr("PIUnits"), "Q"_tr ("PIUnits") , 30 , pow10(30. ), false}},
{Deci, {"deci"_tr ("PIUnits"), "d"_tr ("PIUnits") , -1 , pow10(-1. ), true }},
{Centi, {"centi"_tr ("PIUnits"), "c"_tr ("PIUnits") , -2 , pow10(-2. ), true }},
{Milli, {"milli"_tr ("PIUnits"), "m"_tr ("PIUnits") , -3 , pow10(-3. ), false}},
{Micro, {"micro"_tr ("PIUnits"), "u"_tr ("PIUnits") , -6 , pow10(-6. ), false}},
{Nano, {"nano"_tr ("PIUnits"), "n"_tr ("PIUnits") , -9 , pow10(-9. ), false}},
{Pico, {"pico"_tr ("PIUnits"), "p"_tr ("PIUnits") , -12, pow10(-12.), false}},
{Femto, {"femto"_tr ("PIUnits"), "f"_tr ("PIUnits") , -15, pow10(-15.), false}},
{Atto, {"atto"_tr ("PIUnits"), "a"_tr ("PIUnits") , -18, pow10(-18.), false}},
{Zepto, {"zepto"_tr ("PIUnits"), "z"_tr ("PIUnits") , -21, pow10(-21.), false}},
{Yocto, {"yocto"_tr ("PIUnits"), "y"_tr ("PIUnits") , -24, pow10(-24.), false}},
{Ronto, {"ronto"_tr ("PIUnits"), "r"_tr ("PIUnits") , -27, pow10(-27.), false}},
};
// clang-format on
auto it = prefixes.makeIterator();
while (it.next()) {
prefixes_by_pow[it.value().pow] = &it.value();
}
prefixes_by_pow[0] = &def_prefix;
}
const PIUnits::Prefix::P PIUnits::Prefix::getPrefixForValue(double v, bool use_non3, bool use_greater, bool use_smaller) const {
auto it = prefixes_by_pow.makeIterator();
const P * ret = &def_prefix;
while (it.next()) {
if (it.value()->pow < 0 && !use_smaller) continue;
if (it.value()->pow > 0 && !use_greater) continue;
if (it.value()->non3 && !use_non3) continue;
if (v < it.value()->divider) return *ret;
ret = it.value();
}
return def_prefix;
}
const PIUnits::Prefix::P PIUnits::Prefix::getPrefix(int p) const {
return prefixes.value(p, def_prefix);
}
PIUnits::Prefix & PIUnits::Prefix::instance() {
static Prefix ret;
return ret;
}