LibreVNA/Software/PC_Application/unit.cpp
2021-10-21 08:31:31 -03:00

94 lines
2.7 KiB
C++

#include "unit.h"
#include <math.h>
#include <sstream>
#include <iomanip>
#include <QDebug>
using namespace std;
double Unit::FromString(QString string, QString unit, QString prefixes)
{
if(string.size() == 0) {
return std::numeric_limits<double>::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<double>::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<double>::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;
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;
}
}