/* 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; }