#include "unit.h" #include #include #include #include using namespace std; double Unit::FromString(QString string, QString unit, QString prefixes) { if(string.size() == 0) { return std::numeric_limits::quiet_NaN(); } // remove unit if present if(string.endsWith(unit, Qt::CaseInsensitive)) { string.chop(unit.size()); } // check if last char is a valid prefix double factor = 1.0; if(prefixes.contains(string.at(string.size()-1))) { QChar prefix = string.at(string.size()-1); factor = SIPrefixToFactor(prefix.toLatin1()); string.chop(1); } bool convertOk; auto value = string.toDouble(&convertOk); if(!convertOk) { return std::numeric_limits::quiet_NaN(); } return value * factor; } QString Unit::ToString(double value, QString unit, QString prefixes, int precision) { // change label text QString sValue; if(isnan(value) || isinf(value)) { sValue.append("NaN"); return sValue; } else if(abs(value) <= numeric_limits::epsilon()) { sValue.append("0 "); } else { if(value < 0) { sValue.append('-'); value = -value; } int prefixIndex = 0; //prefixes.indexOf(' '); int preDotDigits = log10(value / SIPrefixToFactor(prefixes[prefixIndex].toLatin1())) + (1.0-log10(0.5)); while(preDotDigits > 3 && prefixIndex < prefixes.length() - 1) { prefixIndex++; preDotDigits = log10(value / SIPrefixToFactor(prefixes[prefixIndex].toLatin1())) + 1; } value /= SIPrefixToFactor(prefixes[prefixIndex].toLatin1()); stringstream ss; ss << std::fixed; if(precision < 0) { precision = 0; } if(preDotDigits >= 0) { if(precision - preDotDigits < 0) { ss << std::setprecision(0); } else { ss << std::setprecision(precision - preDotDigits); } } else { ss << std::setprecision(precision - 2); } ss << value; sValue.append(QString::fromStdString(ss.str())); sValue.append(prefixes[prefixIndex]); } sValue.append(unit); return sValue; } double Unit::SIPrefixToFactor(char prefix) { switch(prefix) { case 'f': return 1e-15; break; case 'p': return 1e-12; break; case 'n': return 1e-9; break; case 'u': return 1e-6; break; case 'm': return 1e-3; break; case ' ': return 1e0; break; case 'k': return 1e3; break; case 'M': return 1e6; break; case 'G': return 1e9; break; case 'T': return 1e12; break; case 'P': return 1e15; break; default: return 1e0; break; } }