CAngleUnit::sexagesimalDeg(), moved conversion to virtual method in CMeasurmenetUnit, made string conversion virtual and also moved it to CMeasurmenetUnit (=>individual formatters). Time unit added.

This commit is contained in:
Klaus Basan
2013-03-31 00:35:25 +01:00
parent be34b78425
commit f77258343d
17 changed files with 542 additions and 299 deletions

View File

@@ -19,24 +19,25 @@ int main(int argc, char *argv[])
// cases which must not work // cases which must not work
// CMeasurementUnit mu; //must not work // CMeasurementUnit mu; //must not work
// CLengthUnit du1(CAngleUnit::rad()); // CLengthUnit du1(CAngleUnit::rad());
CLengthUnit du2(CLengthUnit::cm()); CLengthUnit lu1(CLengthUnit::cm());
CLengthUnit du3(CLengthUnit::ft()); CLengthUnit lu2(CLengthUnit::ft());
const CLength d1(5.0, CLengthUnit::ft()); // 5 ft qDebug() << lu1 << lu2;
CLength d2(1, CLengthUnit::NM()); // 1NM const CLength l1(5.0, CLengthUnit::ft()); // 5 ft
CLength d3(1, CLengthUnit::km()); CLength l2(1, CLengthUnit::NM()); // 1NM
CLength d4(d3); CLength l3(1, CLengthUnit::km());
CLength l4(l3);
qDebug() << CLengthUnit::ft(); qDebug() << CLengthUnit::ft();
qDebug() << d1 << d2 << d3 << d4; qDebug() << l1 << l2 << l3 << l4;
qDebug() << d1.valueRoundedWithUnit(CLengthUnit::ft(),5) qDebug() << l1.valueRoundedWithUnit(CLengthUnit::ft(),5)
<< d2.valueRoundedWithUnit(CLengthUnit::km()); << l2.valueRoundedWithUnit(CLengthUnit::km());
qDebug() << d3.getUnit(); qDebug() << l3.getUnit();
d2.switchUnit(CLengthUnit::ft()); // now in ft l2.switchUnit(CLengthUnit::ft()); // now in ft
d3 += d3; // 2km now l3 += l3; // 2km now
d3 *= 1.5;// 3km now l3 *= 1.5;// 3km now
qDebug() << d2 << d3; qDebug() << l2 << l3;
CFrequency f1(1E6, CFrequencyUnit::Hz()); // 1MHz CFrequency f1(1E6, CFrequencyUnit::Hz()); // 1MHz
qDebug() << f1 << f1.valueRoundedWithUnit(CFrequencyUnit::MHz()) << f1.valueRoundedWithUnit(CFrequencyUnit::GHz(), 3); qDebug() << f1 << f1.valueRoundedWithUnit(CFrequencyUnit::MHz()) << f1.valueRoundedWithUnit(CFrequencyUnit::GHz(), 3);
@@ -50,6 +51,8 @@ int main(int argc, char *argv[])
CAngle a1(180, CAngleUnit::deg()); CAngle a1(180, CAngleUnit::deg());
CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad()); CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad());
CAngle a3(180.5, CAngleUnit::deg());
CAngle a4(35.4336,CAngleUnit::sexagesimalDeg()); // 35.72666
a1 += a2; a1 += a2;
// a1 = d2; // must not work // a1 = d2; // must not work
qDebug() << a1; qDebug() << a1;
@@ -60,6 +63,9 @@ int main(int argc, char *argv[])
a2.switchUnit(CAngleUnit::deg()); a2.switchUnit(CAngleUnit::deg());
qDebug() << a1.unitValueRoundedWithUnit() << a1.piFactor(); qDebug() << a1.unitValueRoundedWithUnit() << a1.piFactor();
qDebug() << a2; qDebug() << a2;
a3.switchUnit(CAngleUnit::sexagesimalDeg());
a4.switchUnit(CAngleUnit::deg());
qDebug() << a3 << a4;
CMass w1(1,CMassUnit::t()); CMass w1(1,CMassUnit::t());
CMass w2(w1); CMass w2(w1);
@@ -88,6 +94,11 @@ int main(int argc, char *argv[])
CLengthUnit duB(CLengthUnit::cm()); CLengthUnit duB(CLengthUnit::cm());
qDebug() << duB; qDebug() << duB;
CTime ti1(1, CTimeUnit::h());
CTime ti2(ti1);
ti2.switchUnit(CTimeUnit::ms());
qDebug() << ti1 << ti2;
// bye // bye
return a.exec(); return a.exec();
} }

View File

@@ -20,7 +20,10 @@ public:
*/ */
CAviationVerticalPosition(); CAviationVerticalPosition();
/*! /*!
* \brief Default constructor * \brief Constructor
* \param height
* \param elevation
* \param altitude
*/ */
CAviationVerticalPosition(const CLength &height, const CLength &elevation, const CLength &altitude); CAviationVerticalPosition(const CLength &height, const CLength &elevation, const CLength &altitude);
/*! /*!
@@ -34,6 +37,18 @@ public:
* \return * \return
*/ */
static CAviationVerticalPosition getHeight(const CLength &initValue) { return CAviationVerticalPosition(initValue, CAviationVerticalPosition::valueNotSet(), CAviationVerticalPosition::valueNotSet());} static CAviationVerticalPosition getHeight(const CLength &initValue) { return CAviationVerticalPosition(initValue, CAviationVerticalPosition::valueNotSet(), CAviationVerticalPosition::valueNotSet());}
/*!
* \brief Factory method for convenience if only one component is available
* \param initValue
* \return
*/
static CAviationVerticalPosition getElevation(const CLength &initValue) { return CAviationVerticalPosition(CAviationVerticalPosition::valueNotSet(), initValue, CAviationVerticalPosition::valueNotSet());}
/*!
* \brief Factory method for convenience if only one component is available
* \param initValue
* \return
*/
static CAviationVerticalPosition getAltitude(const CLength &initValue) { return CAviationVerticalPosition(CAviationVerticalPosition::valueNotSet(), CAviationVerticalPosition::valueNotSet(), initValue);}
}; };
} // namespace } // namespace

View File

@@ -48,7 +48,8 @@ HEADERS += \
avverticalposition.h \ avverticalposition.h \
pqunits.h \ pqunits.h \
pqallquantities.h \ pqallquantities.h \
pqlength.h pqlength.h \
pqtime.h
SOURCES += \ SOURCES += \
logmessage.cpp \ logmessage.cpp \
@@ -71,7 +72,7 @@ SOURCES += \
message_system.cpp \ message_system.cpp \
pqphysicalquantity.cpp \ pqphysicalquantity.cpp \
pqbase.cpp \ pqbase.cpp \
pqtemperature.cpp \ pqunits.cpp \
avverticalposition.cpp avverticalposition.cpp
DESTDIR = ../../lib DESTDIR = ../../lib

View File

@@ -13,6 +13,6 @@
#include "blackmisc/pqspeed.h" #include "blackmisc/pqspeed.h"
#include "blackmisc/pqtemperature.h" #include "blackmisc/pqtemperature.h"
#include "blackmisc/pqangle.h" #include "blackmisc/pqangle.h"
#include "blackmisc/pqtime.h"
#endif // PQUNITSALL_H #endif // PQUNITSALL_H

View File

@@ -45,7 +45,7 @@ public:
* \brief Value as factor of PI (e.g.0.5PI) * \brief Value as factor of PI (e.g.0.5PI)
* \return * \return
*/ */
double piFactor() const { return CPhysicalQuantity::round(this->convertedSiValueToDouble() / M_PI,6);} double piFactor() const { return CMeasurementUnit::round(this->convertedSiValueToDouble() / M_PI,6);}
}; };
} // namespace } // namespace

View File

@@ -10,7 +10,7 @@ namespace BlackMisc {
* Constructor * Constructor
*/ */
CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &unitName, double factor): CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &unitName, double factor):
_name(name),_prefix(unitName),_factor(factor) m_name(name),m_prefix(unitName),m_factor(factor)
{ {
// void // void
} }
@@ -19,7 +19,7 @@ CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &unitN
* Constructor * Constructor
*/ */
CMeasurementPrefix::CMeasurementPrefix(const CMeasurementPrefix &otherMultiplier) : CMeasurementPrefix::CMeasurementPrefix(const CMeasurementPrefix &otherMultiplier) :
_name(otherMultiplier._name), _prefix(otherMultiplier._prefix), _factor(otherMultiplier._factor) m_name(otherMultiplier.m_name), m_prefix(otherMultiplier.m_prefix), m_factor(otherMultiplier.m_factor)
{ {
// void // void
} }
@@ -30,9 +30,9 @@ CMeasurementPrefix::CMeasurementPrefix(const CMeasurementPrefix &otherMultiplier
CMeasurementPrefix& CMeasurementPrefix::operator=(const CMeasurementPrefix &otherMultiplier) { CMeasurementPrefix& CMeasurementPrefix::operator=(const CMeasurementPrefix &otherMultiplier) {
if (this == &otherMultiplier) return *this; // Same object? Yes, so skip assignment, and just return *this if (this == &otherMultiplier) return *this; // Same object? Yes, so skip assignment, and just return *this
this->_name = otherMultiplier._name; this->m_name = otherMultiplier.m_name;
this->_prefix=otherMultiplier._prefix; this->m_prefix=otherMultiplier.m_prefix;
this->_factor=otherMultiplier._factor; this->m_factor=otherMultiplier.m_factor;
return *this; return *this;
} }
@@ -42,7 +42,7 @@ CMeasurementPrefix& CMeasurementPrefix::operator=(const CMeasurementPrefix &othe
bool CMeasurementPrefix::operator ==(const CMeasurementPrefix &otherMultiplier) const bool CMeasurementPrefix::operator ==(const CMeasurementPrefix &otherMultiplier) const
{ {
if ( this == &otherMultiplier ) return true; if ( this == &otherMultiplier ) return true;
return this->_factor == otherMultiplier._factor && this->_name == otherMultiplier._name; return this->m_factor == otherMultiplier.m_factor && this->m_name == otherMultiplier.m_name;
} }
/** /**
@@ -58,7 +58,7 @@ bool CMeasurementPrefix::operator !=(const CMeasurementPrefix &otherMultiplier)
*/ */
bool CMeasurementPrefix::operator >(const CMeasurementPrefix &otherMultiplier) const bool CMeasurementPrefix::operator >(const CMeasurementPrefix &otherMultiplier) const
{ {
return this->_factor > otherMultiplier._factor; return this->m_factor > otherMultiplier.m_factor;
} }
/** /**
@@ -66,7 +66,7 @@ bool CMeasurementPrefix::operator >(const CMeasurementPrefix &otherMultiplier) c
*/ */
bool CMeasurementPrefix::operator <(const CMeasurementPrefix &otherMultiplier) const bool CMeasurementPrefix::operator <(const CMeasurementPrefix &otherMultiplier) const
{ {
return this->_factor < otherMultiplier._factor; return this->m_factor < otherMultiplier.m_factor;
} }
/** /**
@@ -74,7 +74,7 @@ bool CMeasurementPrefix::operator <(const CMeasurementPrefix &otherMultiplier) c
*/ */
QDebug operator<<(QDebug d, const CMeasurementPrefix &multiplier) QDebug operator<<(QDebug d, const CMeasurementPrefix &multiplier)
{ {
d << multiplier._name; d << multiplier.m_name;
return d; return d;
} }
@@ -83,7 +83,7 @@ QDebug operator<<(QDebug d, const CMeasurementPrefix &multiplier)
*/ */
CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier) CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier)
{ {
log << multiplier._name; log << multiplier.m_name;
return log; return log;
} }
@@ -95,8 +95,8 @@ CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier)
* Constructor * Constructor
*/ */
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon): CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon):
_name(name), _unitName(unitName), _type(type), _isSIUnit(isSIUnit), _isSIBaseUnit(isSIBaseUnit),_displayDigits(displayDigits),_conversionFactorToSIConversionUnit(conversionFactorToSI), m_name(name), m_unitName(unitName), m_type(type), m_isSIUnit(isSIUnit), m_isSIBaseUnit(isSIBaseUnit),m_displayDigits(displayDigits),m_conversionFactorToSIConversionUnit(conversionFactorToSI),
_epsilon(epsilon), _multiplier(multiplier) m_epsilon(epsilon), m_multiplier(multiplier)
{ {
// void // void
} }
@@ -105,9 +105,9 @@ CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName,
* Copy constructor * Copy constructor
*/ */
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &otherUnit): CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &otherUnit):
_name(otherUnit._name), _unitName(otherUnit._unitName), _type(otherUnit._type), _isSIUnit(otherUnit._isSIUnit), m_name(otherUnit.m_name), m_unitName(otherUnit.m_unitName), m_type(otherUnit.m_type), m_isSIUnit(otherUnit.m_isSIUnit),
_isSIBaseUnit(otherUnit._isSIBaseUnit), _displayDigits(otherUnit._displayDigits),_conversionFactorToSIConversionUnit(otherUnit._conversionFactorToSIConversionUnit), m_isSIBaseUnit(otherUnit.m_isSIBaseUnit), m_displayDigits(otherUnit.m_displayDigits),m_conversionFactorToSIConversionUnit(otherUnit.m_conversionFactorToSIConversionUnit),
_epsilon(otherUnit._epsilon), _multiplier(otherUnit._multiplier) m_epsilon(otherUnit.m_epsilon), m_multiplier(otherUnit.m_multiplier)
{ {
// void // void
} }
@@ -118,15 +118,15 @@ CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &otherUnit):
CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &otherUnit) CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &otherUnit)
{ {
if (this == &otherUnit) return *this; // Same object? Yes, so skip assignment, and just return *this if (this == &otherUnit) return *this; // Same object? Yes, so skip assignment, and just return *this
this->_name = otherUnit._name; this->m_name = otherUnit.m_name;
this->_unitName =otherUnit._unitName; this->m_unitName =otherUnit.m_unitName;
this->_type=otherUnit._type; this->m_type=otherUnit.m_type;
this->_isSIUnit =otherUnit._isSIUnit; this->m_isSIUnit =otherUnit.m_isSIUnit;
this->_isSIBaseUnit =otherUnit._isSIBaseUnit; this->m_isSIBaseUnit =otherUnit.m_isSIBaseUnit;
this->_conversionFactorToSIConversionUnit=otherUnit._conversionFactorToSIConversionUnit; this->m_conversionFactorToSIConversionUnit=otherUnit.m_conversionFactorToSIConversionUnit;
this->_multiplier = otherUnit._multiplier; this->m_multiplier = otherUnit.m_multiplier;
this->_displayDigits=otherUnit._displayDigits; this->m_displayDigits=otherUnit.m_displayDigits;
this->_epsilon= otherUnit._epsilon; this->m_epsilon= otherUnit.m_epsilon;
return *this; return *this;
} }
@@ -136,9 +136,9 @@ CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &otherUnit
bool CMeasurementUnit::operator ==(const CMeasurementUnit &otherUnit) const bool CMeasurementUnit::operator ==(const CMeasurementUnit &otherUnit) const
{ {
if ( this == &otherUnit ) return true; if ( this == &otherUnit ) return true;
if ( this->_type != otherUnit._type) return false; if ( this->m_type != otherUnit.m_type) return false;
return this->_multiplier == otherUnit._multiplier && this->_name == otherUnit._name return this->m_multiplier == otherUnit.m_multiplier && this->m_name == otherUnit.m_name
&& this->_isSIUnit==otherUnit._isSIUnit; && this->m_isSIUnit==otherUnit.m_isSIUnit;
} }
/** /**
@@ -146,7 +146,7 @@ bool CMeasurementUnit::operator ==(const CMeasurementUnit &otherUnit) const
*/ */
QDebug operator <<(QDebug d, const CMeasurementUnit &unit) QDebug operator <<(QDebug d, const CMeasurementUnit &unit)
{ {
d << unit._name; d << unit.m_name;
return d; return d;
} }
@@ -155,7 +155,7 @@ QDebug operator <<(QDebug d, const CMeasurementUnit &unit)
*/ */
CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit) CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit)
{ {
log << unit._name; log << unit.m_name;
return log; return log;
} }
@@ -170,19 +170,49 @@ bool CMeasurementUnit::operator !=(const CMeasurementUnit &otherUnit) const
/** /**
* Conversion factor from unit x to y * Conversion factor from unit x to y
*/ */
double CMeasurementUnit::conversionFactor(const CMeasurementUnit &to) const double CMeasurementUnit::conversionToUnit(double value, const CMeasurementUnit &to) const
{ {
return CMeasurementUnit::conversionFactor(*this, to); if (to == (*this)) return value;
double siValue = this->convertToSiConversionUnit(value);
return to.convertFromSiConversionUnit(siValue);
}
/*!
* Value to QString with unit, e.g. "5.00m"
* @return
*/
QString CMeasurementUnit::valueRoundedWithUnit(double value, int digits) const {
return this->toQStringRounded(value, digits).append(this->getUnitName());
}
/*!
* Value rounded
*/
double CMeasurementUnit::valueRounded(double value, int digits) const {
if (digits < 0) digits = this->m_displayDigits;
return CMeasurementUnit::round(value, digits);
} }
/** /**
* Conversion factor from unit x to y * Rounded to QString
*/ */
double CMeasurementUnit::conversionFactor(const CMeasurementUnit &from, const CMeasurementUnit &to) QString CMeasurementUnit::toQStringRounded(double value, int digits) const
{ {
if (from == to) return 1.0; if (digits < 0) digits = this->m_displayDigits;
double cf = from._conversionFactorToSIConversionUnit / to._conversionFactorToSIConversionUnit; double v = CMeasurementUnit::round(value, digits);
return cf; QString s = QLocale::system().toString(v, 'f', digits);
return s;
} }
} // namespace BlackCore /**
* Round utility method
*/
double CMeasurementUnit::round(double value, int digits) {
// gosh, is there no Qt method for this???
// It's year 2013
double m = pow(10.0,digits);
double rv = double(qRound(value * m) / m);
return rv;
}
} // namespace

View File

@@ -36,9 +36,9 @@ class CMeasurementPrefix {
friend CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier); friend CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier);
private: private:
QString _name; //!< name, e.g. "kilo" QString m_name; //!< name, e.g. "kilo"
QString _prefix; //!< prefix, e.g. "k" for kilo QString m_prefix; //!< prefix, e.g. "k" for kilo
double _factor; //!< factor, e.g. 1000 for kilo 1/100 for centi double m_factor; //!< factor, e.g. 1000 for kilo 1/100 for centi
/*! /*!
* Constructor by parameters * Constructor by parameters
* \brief CMeasurementMultiplier * \brief CMeasurementMultiplier
@@ -86,26 +86,26 @@ public:
/*! /*!
* \brief Cast as double * \brief Cast as double
*/ */
operator double() const { return this->_factor; } operator double() const { return this->m_factor; }
/*! /*!
* \brief Cast as QString * \brief Cast as QString
*/ */
operator QString() const { return this->_name;} operator QString() const { return this->m_name;}
/*! /*!
* \brief Factor, e.g.1000 for "kilo" * \brief Factor, e.g.1000 for "kilo"
* \return * \return
*/ */
double getFactor() const { return this->_factor;} double getFactor() const { return this->m_factor;}
/*! /*!
* \brief Name, e.g. "kilo" * \brief Name, e.g. "kilo"
* \return * \return
*/ */
QString getName() const { return this->_name; } QString getName() const { return this->m_name; }
/*! /*!
* \brief Prefix, e.g. "k" for "kilo" * \brief Prefix, e.g. "k" for "kilo"
* \return * \return
*/ */
QString getPrefix() const { return this->_prefix; } QString getPrefix() const { return this->m_prefix; }
// --- static units, always use these for initialization // --- static units, always use these for initialization
// --- Remark: Static initialization in C++ is random, this is why no static members // --- Remark: Static initialization in C++ is random, this is why no static members
@@ -115,37 +115,43 @@ public:
* \brief Unit "None" * \brief Unit "None"
* \return * \return
*/ */
static CMeasurementPrefix& None() { static CMeasurementPrefix none("", "", 0.0); return none;} static const CMeasurementPrefix& None() { static CMeasurementPrefix none("", "", 0.0); return none;}
/*! /*!
* \brief Unit "One" * \brief Unit "One"
* \return * \return
*/ */
static CMeasurementPrefix& One() { static CMeasurementPrefix one("one", "", 1.0); return one;} static const CMeasurementPrefix& One() { static CMeasurementPrefix one("one", "", 1.0); return one;}
/*! /*!
* \brief Unit "mega" * \brief Unit "mega"
* \return * \return
*/ */
static CMeasurementPrefix& M() { static CMeasurementPrefix mega("mega", "M", 1E6); return mega;} static const CMeasurementPrefix& M() { static CMeasurementPrefix mega("mega", "M", 1E6); return mega;}
/*! /*!
* \brief Unit "kilo" * \brief Unit "kilo"
* \return * \return
*/ */
static CMeasurementPrefix& k() { static CMeasurementPrefix kilo("kilo", "k", 1000.0); return kilo;} static const CMeasurementPrefix& k() { static CMeasurementPrefix kilo("kilo", "k", 1000.0); return kilo;}
/*! /*!
* \brief Unit "giga" * \brief Unit "giga"
* \return * \return
*/ */
static CMeasurementPrefix& G() { static CMeasurementPrefix giga("giga", "G", 1E9); return giga;} static const CMeasurementPrefix& G() { static CMeasurementPrefix giga("giga", "G", 1E9); return giga;}
/*! /*!
* \brief Unit "hecto" * \brief Unit "hecto"
* \return * \return
*/ */
static CMeasurementPrefix& h() { static CMeasurementPrefix hecto("hecto", "h", 100.0); return hecto;} static const CMeasurementPrefix& h() { static CMeasurementPrefix hecto("hecto", "h", 100.0); return hecto;}
/*! /*!
* \brief Unit "centi" * \brief Unit "centi"
* \return * \return
*/ */
static CMeasurementPrefix& c() { static CMeasurementPrefix centi("centi", "c", 0.01); return centi;} static const CMeasurementPrefix& c() { static CMeasurementPrefix centi("centi", "c", 0.01); return centi;}
/*!
* \brief Unit "milli"
* \return
*/
static const CMeasurementPrefix& m() { static CMeasurementPrefix milli("milli", "m", 1E-03); return milli;}
}; };
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
@@ -174,20 +180,19 @@ class CMeasurementUnit {
friend CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit); friend CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit);
private: private:
QString _name; //!< name, e.g. "meter" QString m_name; //!< name, e.g. "meter"
QString _unitName; //!< unit name, e.g. "m" QString m_unitName; //!< unit name, e.g. "m"
QString _type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons QString m_type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons
bool _isSIUnit; //!< is this a SI unit? bool m_isSIUnit; //!< is this a SI unit?
bool _isSIBaseUnit; //!< SI base unit? bool m_isSIBaseUnit; //!< SI base unit?
double _conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature) double m_conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature)
double _epsilon; //!< values with differences below epsilon are the equal double m_epsilon; //!< values with differences below epsilon are the equal
qint32 _displayDigits; //!< standard rounding dor string conversions qint32 m_displayDigits; //!< standard rounding dor string conversions
CMeasurementPrefix _multiplier; //!< multiplier CMeasurementPrefix m_multiplier; //!< multiplier (kilo, Mega)
protected: protected:
/*! /*!
* Constructor by parameter * Constructor by parameter
*\brief CMeasurementUnit
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
@@ -209,6 +214,12 @@ protected:
* \return * \return
*/ */
CMeasurementUnit &operator =(const CMeasurementUnit &otherUnit); CMeasurementUnit &operator =(const CMeasurementUnit &otherUnit);
protected:
/*!
* \brief Conversion factor to SI conversion unit
* \return
*/
double getConversionFactorToSI() const { return this->m_conversionFactorToSIConversionUnit; }
public: public:
/*! /*!
@@ -227,65 +238,101 @@ public:
* \brief Representing an SI unit? Examples: kilometer, meter, hertz * \brief Representing an SI unit? Examples: kilometer, meter, hertz
* \return * \return
*/ */
bool isSiUnit() const { return this->_isSIUnit;} bool isSiUnit() const { return this->m_isSIUnit;}
/*! /*!
* \brief Representing an base SI unit? Examples: second, meter * \brief Representing an base SI unit? Examples: second, meter
* \return * \return
*/ */
bool isSiBaseUnit() const { return this->_isSIUnit;} bool isSiBaseUnit() const { return this->m_isSIUnit;}
/*! /*!
* \brief Representing an SI base unit? Example: meter * \brief Representing an SI base unit? Example: meter
* \return * \return
*/ */
bool isUnprefixedSiUnit() const { return this->_isSIUnit && this->_multiplier.getFactor() == 1; } bool isUnprefixedSiUnit() const { return this->m_isSIUnit && this->m_multiplier.getFactor() == 1; }
/*! /*!
* \brief Name such as "meter" * \brief Name such as "meter"
* \return * \return
*/ */
QString getName() const { return this->_name; } QString getName() const { return this->m_name; }
/*! /*!
* \brief Unit name such as "m" * \brief Unit name such as "m"
* \return * \return
*/ */
QString getUnitName() const { return this->_unitName; } QString getUnitName() const { return this->m_unitName; }
/*!
* \brief Factor toconvert to SI unit (e.g.meter,hertz)
* \return
*/
QString getType() const { return this->_type; }
/*! /*!
* \brief Type such as "distance", "frequency" * \brief Type such as "distance", "frequency"
* \return * \return
*/ */
double getConversionFactorToSIConversionUnit() const { return this->_conversionFactorToSIConversionUnit;} QString getType() const { return this->m_type; }
/*!
* Given value to conversion SI conversion unit (e.g. meter, hertz).
* Standard implementaion is simply factor based.
* \param value
* \return
*/
virtual double convertToSiConversionUnit(double value) const { return value * this->m_conversionFactorToSIConversionUnit; }
/*!
* \brief Value from SI conversion unit to this unit.
* Standard implementaion is simply factor based.
* \param value
* \return
*/
virtual double convertFromSiConversionUnit(double value) const { return value / this->m_conversionFactorToSIConversionUnit; }
/*!
* Rounded string utility method, virtual so units can have
* specialized formatting
* \param value
* \param digits
* \return
*/
virtual QString toQStringRounded(double value, int digits =-1) const;
/*!
* \brief Rounded value
* \param value
* \param digits
* \return
*/
double valueRounded(double value, int digits = -1) const;
/*!
* \brief Value rounded with unit, e.g. "5.00m", "30kHz"
* \param value
* \param digits
* \return
*/
virtual QString valueRoundedWithUnit(double value, int digits = -1) const;
/*! /*!
* \brief Threshold for rounding * \brief Threshold for rounding
* \return * \return
*/ */
double getEpsilon() const { return this->_epsilon;} double getEpsilon() const { return this->m_epsilon;}
/*! /*!
* \brief getDisplayDigits * \brief getDisplayDigits
* \return * \return
*/ */
qint32 getDisplayDigits() const { return this->_displayDigits; } qint32 getDisplayDigits() const { return this->m_displayDigits; }
/*! /*!
* \brief Multiplier such as "kilo" * \brief Multiplier such as "kilo"
* \return * \return
*/ */
CMeasurementPrefix getMultiplier() const { return this->_multiplier; } CMeasurementPrefix getMultiplier() const { return this->m_multiplier; }
/*! /*!
* \brief Factor to convert to given unit * \brief Factor to convert to given unit
* \param to * \param to
* \return * \return
*/ */
double conversionFactor(const CMeasurementUnit &to) const; double conversionToUnit(double value, const CMeasurementUnit &to) const;
// --------------------------------------------------------------------
// -- static
// --------------------------------------------------------------------
/*! /*!
* \brief Factor to convert between given units * \brief Utility round method
* \param from * \param value
* \param to * \param digits
* \return * \return
*/ */
static double conversionFactor(const CMeasurementUnit &from, const CMeasurementUnit &to); static double round(double value, int digits);
/*! /*!
* \brief Unit is not specified * \brief Unit is not specified
* \return * \return
@@ -293,6 +340,6 @@ public:
static CMeasurementUnit& None() { static CMeasurementUnit none("none", "", "", false, false, 0.0, CMeasurementPrefix::None(), 0, 0); return none;} static CMeasurementUnit& None() { static CMeasurementUnit none("none", "", "", false, false, 0.0, CMeasurementPrefix::None(), 0, 0); return none;}
}; };
} // namespace BlackMisc } // namespace
#endif // PQBASE_H #endif // PQBASE_H

View File

@@ -5,8 +5,8 @@ namespace BlackMisc {
/** /**
* Constructor by integer * Constructor by integer
*/ */
template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit) :
m_unit(unit), m_conversionSiUnit(siConversionUnit), m_unitConverter(unitConverter) m_unit(unit), m_conversionSiUnit(siConversionUnit)
{ {
this->setUnitValue(baseValue); this->setUnitValue(baseValue);
} }
@@ -14,8 +14,8 @@ template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(qint32
/** /**
* Constructor by double * Constructor by double
*/ */
template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit, const CPhysicalQuantityUnitConverter unitConverter) : template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit) :
m_unit(unit), m_conversionSiUnit(siConversionUnit),m_unitConverter(unitConverter) m_unit(unit), m_conversionSiUnit(siConversionUnit)
{ {
this->setUnitValue(baseValue); this->setUnitValue(baseValue);
} }
@@ -25,7 +25,7 @@ template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(double
*/ */
template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) : template <class MU, class PQ> CPhysicalQuantity<MU,PQ>::CPhysicalQuantity(const CPhysicalQuantity &otherQuantity) :
m_unitValueD(otherQuantity.m_unitValueD), m_unitValueI(otherQuantity.m_unitValueI), m_convertedSiUnitValueD(otherQuantity.m_convertedSiUnitValueD), m_unitValueD(otherQuantity.m_unitValueD), m_unitValueI(otherQuantity.m_unitValueI), m_convertedSiUnitValueD(otherQuantity.m_convertedSiUnitValueD),
m_isIntegerBaseValue(otherQuantity.m_isIntegerBaseValue), m_unit(otherQuantity.m_unit), m_conversionSiUnit(otherQuantity.m_conversionSiUnit), m_unitConverter(otherQuantity.m_unitConverter) m_isIntegerBaseValue(otherQuantity.m_isIntegerBaseValue), m_unit(otherQuantity.m_unit), m_conversionSiUnit(otherQuantity.m_conversionSiUnit)
{ {
// void // void
} }
@@ -46,7 +46,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU,PQ>::operator ==(const C
if(this == &otherQuantity) return true; if(this == &otherQuantity) return true;
if(this->m_unit.getType()!= otherQuantity.m_unit.getType()) return false; if(this->m_unit.getType()!= otherQuantity.m_unit.getType()) return false;
// some special case for best quality // some special cases for best quality
double diff; double diff;
const double lenient = 1.001; // even diff already has a rounding issue to be avoided const double lenient = 1.001; // even diff already has a rounding issue to be avoided
if (this->m_unit == otherQuantity.m_unit) { if (this->m_unit == otherQuantity.m_unit) {
@@ -87,7 +87,6 @@ template <class MU, class PQ> CPhysicalQuantity<MU,PQ>& CPhysicalQuantity<MU,PQ>
this->m_isIntegerBaseValue = otherQuantity.m_isIntegerBaseValue; this->m_isIntegerBaseValue = otherQuantity.m_isIntegerBaseValue;
this->m_unit = otherQuantity.m_unit; this->m_unit = otherQuantity.m_unit;
this->m_conversionSiUnit = otherQuantity.m_conversionSiUnit; this->m_conversionSiUnit = otherQuantity.m_conversionSiUnit;
this->m_unitConverter = otherQuantity.m_unitConverter;
return *this; return *this;
} }
@@ -249,7 +248,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU,PQ>::switchUnit(const MU
{ {
if (this->m_unit == newUnit) return true; if (this->m_unit == newUnit) return true;
if (this->m_unit.getType() != newUnit.getType()) return false; // not possible if (this->m_unit.getType() != newUnit.getType()) return false; // not possible
double cf = this->m_unitConverter(this, newUnit); double cf = this->m_unit.conversionToUnit(this->m_unitValueD, newUnit);
this->m_unit = newUnit; this->m_unit = newUnit;
this->setUnitValue(cf); this->setUnitValue(cf);
return true; return true;
@@ -281,17 +280,7 @@ template <class MU, class PQ> void CPhysicalQuantity<MU,PQ>::setUnitValue(double
* Set SI value * Set SI value
*/ */
template <class MU, class PQ> void CPhysicalQuantity<MU,PQ>::setConversionSiUnitValue() { template <class MU, class PQ> void CPhysicalQuantity<MU,PQ>::setConversionSiUnitValue() {
this->m_convertedSiUnitValueD = this->m_unitConverter(this, this->m_conversionSiUnit); this->m_convertedSiUnitValueD = this->m_unit.convertToSiConversionUnit(this->m_unitValueD);
}
/**
* Standard conversion by factor, used in most cases, in some cases (e.g. CTemperature) arbitrary converter
*/
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::standardUnitFactorValueConverter(const CPhysicalQuantity<MU,PQ> *quantity, const MU &otherUnit) {
if (quantity->m_unit == MU::None() || quantity->m_unitValueD == 0.0) return 0.0;
if (quantity->m_unit == otherUnit) return quantity->m_unitValueD;
double f = quantity->m_unit.conversionFactor(otherUnit);
return f * quantity->m_unitValueD;
} }
/** /**
@@ -299,18 +288,7 @@ template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::standardUnitFacto
*/ */
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::unitValueToDoubleRounded(int digits) const template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::unitValueToDoubleRounded(int digits) const
{ {
if (digits < 1) digits = this->m_unit.getDisplayDigits(); return this->m_unit.valueRounded(this->m_unitValueD, digits);
return CPhysicalQuantity<MU,PQ>::round(this->m_unitValueD, digits);
}
/**
* Rounded to QString
*/
template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::toQStringRounded(double value, int digits)
{
double v =CPhysicalQuantity<MU,PQ>::round(value, digits);
QString s = QLocale::system().toString(v, 'f', digits);
return s;
} }
/** /**
@@ -318,8 +296,15 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::toQStringRounded
*/ */
template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::unitValueToQStringRounded(int digits) const template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::unitValueToQStringRounded(int digits) const
{ {
if (digits < 1) digits = this->m_unit.getDisplayDigits(); return this->m_unit.toQStringRounded(this->m_unitValueD, digits);
return CPhysicalQuantity<MU,PQ>::toQStringRounded(this->m_unitValueD, digits); }
/**
* Rounded with unit
*/
template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::unitValueRoundedWithUnit(int digits) const
{
return this->m_unit.valueRoundedWithUnit(this->m_unitValueD, digits);
} }
/** /**
@@ -328,15 +313,7 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::unitValueToQStri
template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::convertedSiValueToQStringRounded(int digits) const template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::convertedSiValueToQStringRounded(int digits) const
{ {
if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits(); if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits();
return CPhysicalQuantity<MU,PQ>::toQStringRounded(this->m_convertedSiUnitValueD, digits); return this->m_conversionSiUnit.toQStringRounded(this->m_convertedSiUnitValueD, digits);
}
/**
* Value rounded in original unit
*/
template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::unitValueRoundedWithUnit(int digits) const {
if (digits < 1) digits = this->m_unit.getDisplayDigits();
return this->unitValueToQStringRounded(digits).append(this->m_unit.getUnitName());
} }
/** /**
@@ -354,8 +331,7 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::valueRoundedWith
{ {
if (unit == this->m_unit) return this->unitValueRoundedWithUnit(digits); if (unit == this->m_unit) return this->unitValueRoundedWithUnit(digits);
if (unit == this->m_conversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits); if (unit == this->m_conversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits);
if (digits < 0) digits = unit.getDisplayDigits(); return unit.valueRoundedWithUnit(this->value(unit),digits);
return CPhysicalQuantity<MU,PQ>::toQStringRounded(this->value(unit), digits).append(unit.getUnitName());
} }
/** /**
@@ -363,8 +339,7 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU,PQ>::valueRoundedWith
*/ */
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::valueRounded(const MU &unit, int digits) const template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::valueRounded(const MU &unit, int digits) const
{ {
if (digits < 1) digits = unit.getDisplayDigits(); return unit.valueRounded(this->value(unit),digits);
return CPhysicalQuantity<MU,PQ>::round(this->value(unit),digits);
} }
/** /**
@@ -372,8 +347,9 @@ template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::valueRounded(cons
*/ */
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::value(const MU &unit) const template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::value(const MU &unit) const
{ {
if (unit == this->m_unit) return this->m_unitValueD;
if (unit == this->m_conversionSiUnit) return this->m_convertedSiUnitValueD; if (unit == this->m_conversionSiUnit) return this->m_convertedSiUnitValueD;
double v = this->m_unitConverter(this, unit); double v = unit.convertFromSiConversionUnit(this->m_convertedSiUnitValueD);
return v; return v;
} }
@@ -383,21 +359,11 @@ template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::value(const MU &u
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::convertedSiValueToDoubleRounded(int digits) const template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::convertedSiValueToDoubleRounded(int digits) const
{ {
if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits(); if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits();
return CPhysicalQuantity<MU,PQ>::round(this->m_convertedSiUnitValueD, digits); return this->m_conversionSiUnit.valueRounded(this->m_convertedSiUnitValueD, digits);
} }
/**
* Round utility method
*/
template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::round(double value, int digits) {
// gosh, is there no Qt method for this???
// It's year 2013
double m = pow(10.0,digits);
double rv = double(qRound(value * m) / m);
return rv;
}
// see here for the reason of this forward initialization // see here for the reason of this forward instants
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html // http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
template class CPhysicalQuantity<CLengthUnit, CLength>; template class CPhysicalQuantity<CLengthUnit, CLength>;
template class CPhysicalQuantity<CPressureUnit, CPressure>; template class CPhysicalQuantity<CPressureUnit, CPressure>;
@@ -406,5 +372,7 @@ template class CPhysicalQuantity<CMassUnit, CMass>;
template class CPhysicalQuantity<CTemperatureUnit, CTemperature>; template class CPhysicalQuantity<CTemperatureUnit, CTemperature>;
template class CPhysicalQuantity<CSpeedUnit, CSpeed>; template class CPhysicalQuantity<CSpeedUnit, CSpeed>;
template class CPhysicalQuantity<CAngleUnit, CAngle>; template class CPhysicalQuantity<CAngleUnit, CAngle>;
template class CPhysicalQuantity<CTimeUnit, CTime>;
} // namespace } // namespace

View File

@@ -23,7 +23,7 @@ template <class MU, class PQ> class CPhysicalQuantity
* Our converter function, should be implemented as static method of the quantity * Our converter function, should be implemented as static method of the quantity
* classes for clarity * classes for clarity
*/ */
typedef double (*CPhysicalQuantityUnitConverter)(const CPhysicalQuantity<MU,PQ> *quantity, const MU &unit); typedef double (*CPhysicalQuantityUnitConverter)(const PQ *quantity, const MU &unit);
/*! /*!
* Stream operator for debugging * Stream operator for debugging
@@ -31,9 +31,9 @@ template <class MU, class PQ> class CPhysicalQuantity
* \param debug * \param debug
* \param quantity * \param quantity
* \return * \return
* \remarks has to be in the header files toavoid templatelink errors * \remarks Has to be in the header files to avoid template link errors
*/ */
friend QDebug operator<<(QDebug debug, const CPhysicalQuantity<MU,PQ> &quantity) { friend QDebug operator<<(QDebug debug, const CPhysicalQuantity &quantity) {
QString v = quantity.unitValueRoundedWithUnit(-1); QString v = quantity.unitValueRoundedWithUnit(-1);
debug << v; debug << v;
return debug; return debug;
@@ -45,9 +45,9 @@ template <class MU, class PQ> class CPhysicalQuantity
* \param log * \param log
* \param quantity * \param quantity
* \return * \return
* \remarks has to be in the header files toavoid templatelink errors * \remarks Has to be in the header files toavoid templatelink errors
*/ */
friend CLogMessage operator<<(CLogMessage log, const CPhysicalQuantity<MU,PQ> &quantity) { friend CLogMessage operator<<(CLogMessage log, const CPhysicalQuantity &quantity) {
QString v = quantity.unitValueRoundedWithUnit(-1); QString v = quantity.unitValueRoundedWithUnit(-1);
log << v; log << v;
return log; return log;
@@ -58,16 +58,6 @@ private:
double m_unitValueD; //!< value backed by double double m_unitValueD; //!< value backed by double
double m_convertedSiUnitValueD; //!< SI unit value double m_convertedSiUnitValueD; //!< SI unit value
bool m_isIntegerBaseValue; //!< flag integer? / double? bool m_isIntegerBaseValue; //!< flag integer? / double?
CPhysicalQuantityUnitConverter m_unitConverter; //! <! converts values between units
/*!
* Convert value in another unit, normally just by a factor, but in some cases
* (e.g. CTemperature) overridden, because arbitrary conversion is required
* \param quantity quanity
* \param otherUnit
* \return
*/
static double standardUnitFactorValueConverter(const CPhysicalQuantity<MU,PQ> *quantity, const MU &otherUnit);
protected: protected:
MU m_unit; //!< unit MU m_unit; //!< unit
@@ -80,16 +70,14 @@ protected:
* \param siBaseUnit * \param siBaseUnit
* \param unitConverter * \param unitConverter
*/ */
CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit, CPhysicalQuantity(qint32 baseValue, const MU &unit, const MU &siConversionUnit);
const CPhysicalQuantityUnitConverter unitConverter = CPhysicalQuantity::standardUnitFactorValueConverter);
/*! /*!
* \brief Constructor with double * \brief Constructor with double
* \param baseValue * \param baseValue
* \param unit * \param unit
* \param siBaseUnit * \param siBaseUnit
*/ */
CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit, CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit);
const CPhysicalQuantityUnitConverter unitConverter = CPhysicalQuantity::standardUnitFactorValueConverter);
/*! /*!
* \brief Init by integer * \brief Init by integer
* \param baseValue * \param baseValue
@@ -110,11 +98,11 @@ public:
* \brief Copy constructor * \brief Copy constructor
* \param otherQuantity * \param otherQuantity
*/ */
CPhysicalQuantity<MU,PQ>(const CPhysicalQuantity<MU,PQ> &otherQuantity); CPhysicalQuantity(const CPhysicalQuantity &otherQuantity);
/*! /*!
* \brief Virtual destructor * \brief Virtual destructor
*/ */
virtual ~CPhysicalQuantity<MU,PQ>(); virtual ~CPhysicalQuantity();
/*! /*!
* \brief Unit of the distance * \brief Unit of the distance
* \return * \return
@@ -146,12 +134,6 @@ public:
* \return * \return
*/ */
bool isUnprefixedSiUnit() const { return this->m_unit.isUnprefixedSiUnit(); } bool isUnprefixedSiUnit() const { return this->m_unit.isUnprefixedSiUnit(); }
/*!
* \brief Value to QString with unit, e.g. "5.00m"
* \param digits
* @return
*/
QString unitValueRoundedWithUnit(int digits = -1) const;
/*! /*!
* \brief Value in given unit * \brief Value in given unit
* \param unit * \param unit
@@ -182,11 +164,17 @@ public:
* @return * @return
*/ */
double unitValueToDouble() const { return this->m_unitValueD;} double unitValueToDouble() const { return this->m_unitValueD;}
/*!
* \brief Value to QString with unit, e.g. "5.00m"
* \param digits
* @return
*/
QString unitValueRoundedWithUnit(int digits = -1) const;
/*! /*!
* \brief SI value to integer * \brief SI value to integer
* @return * @return
*/ */
qint32 siBaseUnitValueToInteger() const { return CPhysicalQuantity::round(this->m_convertedSiUnitValueD,0);} qint32 siBaseUnitValueToInteger() const { return CMeasurementUnit::round(this->m_convertedSiUnitValueD,0);}
/*! /*!
* \brief SI value to double * \brief SI value to double
* @return * @return
@@ -213,7 +201,7 @@ public:
* \brief SI value as integer * \brief SI value as integer
* \return * \return
*/ */
qint32 convertedSiValueToInteger() const { return (qint32)CPhysicalQuantity::round(this->m_convertedSiUnitValueD,0);} qint32 convertedSiValueToInteger() const { return static_cast<qint32>(CMeasurementUnit::round(this->m_convertedSiUnitValueD,0));}
/*! /*!
* \brief Rounded SI value by n digits * \brief Rounded SI value by n digits
* \param digits * \param digits
@@ -258,13 +246,13 @@ public:
* \param multiply * \param multiply
* \return * \return
*/ */
CPhysicalQuantity<MU,PQ> &operator *=(double multiply); CPhysicalQuantity &operator *=(double multiply);
/*! /*!
* \brief Divide operator /= * \brief Divide operator /=
* \param divide * \param divide
* @return * @return
*/ */
CPhysicalQuantity<MU,PQ> &operator /=(double divide); CPhysicalQuantity &operator /=(double divide);
/*! /*!
* \brief Operator * * \brief Operator *
* \param multiply * \param multiply
@@ -282,55 +270,55 @@ public:
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator==(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator==(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Not equal operator != * \brief Not equal operator !=
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator!=(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator!=(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Plus operator += * \brief Plus operator +=
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
CPhysicalQuantity<MU,PQ> &operator +=(const CPhysicalQuantity<MU,PQ> &otherQuantity); CPhysicalQuantity &operator +=(const CPhysicalQuantity &otherQuantity);
/*! /*!
* \brief Minus operator-= * \brief Minus operator-=
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
CPhysicalQuantity<MU,PQ> &operator -=(const CPhysicalQuantity<MU,PQ> &otherQuantity); CPhysicalQuantity &operator -=(const CPhysicalQuantity &otherQuantity);
/*! /*!
* \brief Greater operator > * \brief Greater operator >
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator >(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator >(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Less operator < * \brief Less operator <
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator <(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator <(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Less equal operator <= * \brief Less equal operator <=
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator <=(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator <=(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Greater equal operator >= * \brief Greater equal operator >=
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
bool operator >=(const CPhysicalQuantity<MU,PQ> &otherQuantity) const; bool operator >=(const CPhysicalQuantity &otherQuantity) const;
/*! /*!
* \brief Assignment operator = * \brief Assignment operator =
* \param otherQuantity * \param otherQuantity
* @return * @return
*/ */
CPhysicalQuantity<MU,PQ> &operator =(const CPhysicalQuantity<MU,PQ> &otherQuantity); CPhysicalQuantity &operator =(const CPhysicalQuantity &otherQuantity);
/*! /*!
* \brief Plus operator + * \brief Plus operator +
* \param otherQuantity * \param otherQuantity
@@ -344,26 +332,6 @@ public:
*/ */
PQ operator -(const PQ &otherQuantity) const; PQ operator -(const PQ &otherQuantity) const;
// --------------------------------------------------------------------
// -- static
// --------------------------------------------------------------------
/*!
* \brief Utility round method
* \param value
* \param digits
* \return
*/
static double round(double value, int digits);
/*!
* \brief Rounded string utility method
* \param value
* \param digits
* \return
*/
static QString toQStringRounded(double value, int digits);
}; };
} // namespace BlackCore } // namespace BlackCore

View File

@@ -1,40 +0,0 @@
#include "blackmisc/pqtemperature.h"
namespace BlackMisc {
/**
* Specialized method for temperture
*/
double CTemperature::temperaturUnitConverter(const CPhysicalQuantity<CTemperatureUnit, CTemperature> *quantity, const CTemperatureUnit &otherUnit)
{
CTemperature *me = (CTemperature*) quantity; // allow me access to protected
if (me->m_unit == otherUnit) return me->siBaseUnitValueToDouble();
double siValue;
// I always convert via SI Unit, other I would need too many conversions
if(otherUnit == me->m_conversionSiUnit) {
// here I expect a conversion to SI is required and not done yet
if(me->m_unit == CTemperatureUnit::C()) {
siValue = quantity->unitValueToDouble() + 273.15;
} else if(me->m_unit == CTemperatureUnit::F()) {
siValue = (me->unitValueToDouble() + 459.67) *5.0 / 9.0;
} else{
// TODO: EXCEPTION
}
} else {
// here I expect the SI value is already set
siValue = quantity->siBaseUnitValueToDouble();
}
// from SI
if (otherUnit == me->m_conversionSiUnit) return siValue;
if(otherUnit == CTemperatureUnit::C()) {
return siValue - 273.15;
} else if(me->m_unit == CTemperatureUnit::F()) {
return (siValue * 9.0 / 5.0) - 459.67;
}
// TODO: Exception
return 0;
}
} // namespace

View File

@@ -10,20 +10,11 @@ namespace BlackMisc {
*/ */
class CTemperature : public CPhysicalQuantity<CTemperatureUnit,CTemperature> class CTemperature : public CPhysicalQuantity<CTemperatureUnit,CTemperature>
{ {
private:
/*!
* \brief Convert into another temperature unit
* \param quantity
* \param otherUnit
* \return
*/
static double temperaturUnitConverter(const CPhysicalQuantity<CTemperatureUnit,CTemperature> *quantity, const CTemperatureUnit &otherUnit);
public: public:
/*! /*!
* \brief Default constructor * \brief Default constructor
*/ */
CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::K(), CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::K(), CTemperatureUnit::K()) {}
/** /**
*\brief Copy constructor *\brief Copy constructor
*/ */
@@ -33,13 +24,13 @@ public:
* \param value * \param value
* \param unit * \param unit
*/ */
CTemperature(qint32 value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} CTemperature(qint32 value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K()) {}
/*! /*!
*\brief Init by double value *\brief Init by double value
* \param value * \param value
* \param unit * \param unit
*/ */
CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K(), CTemperature::temperaturUnitConverter) {} CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K()) {}
/*! /*!
* \brief Destructor * \brief Destructor
*/ */

43
src/blackmisc/pqtime.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef PQTIME_H
#define PQTIME_H
#include "pqphysicalquantity.h"
namespace BlackMisc {
/*!
* Time class, e.g. "ms", "hour", "s", "day"
* \author KWB
*/
class CTime : public CPhysicalQuantity<CTimeUnit, CTime>
{
public:
/*!
* \brief Default constructor
*/
CTime() : CPhysicalQuantity(0, CTimeUnit::s(), CTimeUnit::s()) {}
/**
*\brief Copy constructor
*/
CTime(const CPhysicalQuantity &time): CPhysicalQuantity(time) {}
/*!
* \brief Init by int value
* \param value
* \param unit
*/
CTime(qint32 value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit, CTimeUnit::s()) {}
/*!
*\brief Init by double value
* \param value
* \param unit
*/
CTime(double value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit, CTimeUnit::s()) {}
/*!
* \brief Destructor
*/
virtual ~CTime() {}
};
} // namespace
#endif // PQTIME_H

90
src/blackmisc/pqunits.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "blackmisc/pqunits.h"
namespace BlackMisc {
/**
* Convert to SI
*/
double CTemperatureUnit::convertToSiConversionUnit(double value) const
{
double v = value + this->m_conversionOffsetToSi;
v *= this->getConversionFactorToSI();
return v;
}
/**
* Convert from SI
*/
double CTemperatureUnit::convertFromSiConversionUnit(double value) const
{
double v = value / this->getConversionFactorToSI();
v -= this->m_conversionOffsetToSi;
return v;
}
/**
* Convert from SI
*/
double CAngleUnit::convertFromSiConversionUnit(double value) const
{
double v;
// still a design flaw since I have to distinguish as per type
// but an own converter per object was really too much
if ((*this) == CAngleUnit::sexagesimalDeg()) {
value = value * 180 / M_PI; // degree
v = floor(value);
double c = value - v;
double mr = c * 60.0;
double m = floor(mr); // minutes
double s = (mr-m) * 60; // seconds + rest fraction
v = (v + (m/100) + (s/10000));
} else {
v = CMeasurementUnit::convertFromSiConversionUnit(value);
}
return v;
}
/**
* Convert to SI
*/
double CAngleUnit::convertToSiConversionUnit(double value) const
{
// still a design flaw since I have to distinguish as per type
// but an own converter per object was really too much
double v;
if ((*this) == CAngleUnit::sexagesimalDeg()) {
double v = floor(value); // degrees
double c = value - v;
c = c * 100.0;
double m = floor(c);
c = c - m;
m /= 60.0; // minutes back to decimals
double s = c / 36.0; // seconds back to decimals
v = v + m + s;
return v / 180.0 * M_PI;
} else {
v = CMeasurementUnit::convertToSiConversionUnit(value);
}
return v;
}
/**
* Rounded to QString
*/
QString CAngleUnit::toQStringRounded(double value, int digits) const
{
QString s;
if ((*this) == CAngleUnit::sexagesimalDeg()) {
double de = floor(value);
double mi = floor((value-de)*100.0);
double se = floor((value-de-mi/100.0)*1000000) / 100.0;
QString ses = QLocale::system().toString(se, 'f', 2);
s = QString::number(de).append(this->getUnitName()).append(QString::number(mi))
.append("'").append(ses).append("\"");
} else {
s = CMeasurementUnit::toQStringRounded(value, digits);
}
return s;
}
}

View File

@@ -1,18 +1,22 @@
#ifndef PQUNITS_H #ifndef PQUNITS_H
#define PQUNITS_H #define PQUNITS_H
#include "blackmisc/pqbase.h" #include "blackmisc/pqbase.h"
#include <math.h>
//
// Used with the template for quantities. This is the reason for
// having all units in one file, since template requires concrete instantiations
//
namespace BlackMisc { namespace BlackMisc {
/*! /*!
* Specialized class for distance units (meter, foot, nautical miles). * Specialized class for distance units (meter, foot, nautical miles).
* \author KWB * \author KWB, MS
*/ */
class CLengthUnit : public CMeasurementUnit { class CLengthUnit : public CMeasurementUnit {
private: private:
/*! /*!
* Constructor * \brief Constructor Distance unit
* \brief Distance unit
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
@@ -66,8 +70,7 @@ public:
class CAngleUnit : public CMeasurementUnit { class CAngleUnit : public CMeasurementUnit {
private: private:
/*! /*!
* Constructor * \brief Constructor angle units: Radian, degree
* \brief Angle units: Radian, degree
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
@@ -82,20 +85,45 @@ private:
// void // void
} }
public: public:
CAngleUnit(const CAngleUnit &otherUnit) : CMeasurementUnit(otherUnit)
{
// void
}
/*! /*!
* \brief Meter m * \brief Copy constructor
* \param otherUnit
*/
CAngleUnit(const CAngleUnit &otherUnit) : CMeasurementUnit(otherUnit) { }
/*!
* \brief Convert to SI conversion unit, specific for angle
* \param value
* \return
*/
virtual double CAngleUnit::convertToSiConversionUnit(double value) const;
/*!
* \brief Convert from SI conversion unit, specific for angle
* \param value
* \return
*/
virtual double CAngleUnit::convertFromSiConversionUnit(double value) const;
/*!
* \brief Special conversion to QString for sexagesimal degrees.
* \param value
* \param digits
* \return
*/
virtual QString toQStringRounded(double value, int digits) const;
/*!
* \brief Radians
* \return * \return
*/ */
static const CAngleUnit& rad() { static CAngleUnit rad("radian", "rad", true); return rad;} static const CAngleUnit& rad() { static CAngleUnit rad("radian", "rad", true); return rad;}
/*! /*!
* \brief Nautical miles NM * \brief Degrees
* \return * \return
*/ */
static const CAngleUnit& deg() { static CAngleUnit deg("degree", "°", false, M_PI/180); return deg;} static const CAngleUnit& deg() { static CAngleUnit deg("degree", "°", false, M_PI/180); return deg;}
/*!
* \brief Sexagesimal degree (degree, minute, seconds)
* \return
*/
static const CAngleUnit& sexagesimalDeg() { static CAngleUnit deg("segadecimal degree", "°", false, M_PI/180); return deg;}
}; };
/*! /*!
@@ -151,8 +179,7 @@ public:
class CMassUnit : public CMeasurementUnit { class CMassUnit : public CMeasurementUnit {
private: private:
/*! /*!
* Constructor * \brief Constructor mass units
* \brief Mass units
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
@@ -183,7 +210,7 @@ public:
* \brief Tonne, aka metric tonne (1000kg) * \brief Tonne, aka metric tonne (1000kg)
* \return * \return
*/ */
static const CMassUnit& t() { static CMassUnit t("tonne", "t", true, false, 1000.0, CMeasurementPrefix::One(), 3); return t;} static const CMassUnit& t() { static CMassUnit t("tonne", "t", false, false, 1000.0, CMeasurementPrefix::One(), 3); return t;}
/*! /*!
* \brief Pound, aka mass pound * \brief Pound, aka mass pound
* \return * \return
@@ -257,30 +284,51 @@ public:
* \author KWB * \author KWB
*/ */
class CTemperatureUnit : public CMeasurementUnit { class CTemperatureUnit : public CMeasurementUnit {
private:
double m_conversionOffsetToSi;
private: private:
/*! /*!
* Constructor * Constructor temperature unit
* \brief Temperature unit
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
* \param isSIBaseUnit * \param isSIBaseUnit
* \param conversionFactorToSI * \param conversionFactorToSI
* \param temperatureOffsetToSI
* \param mulitplier * \param mulitplier
* \param displayDigits * \param displayDigits
* \param epsilon * \param epsilon
*/ */
CTemperatureUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) : CTemperatureUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, double temperatureOffsetToSI=0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
CMeasurementUnit(name, unitName, "temperature", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} CMeasurementUnit(name, unitName, "temperature", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon), m_conversionOffsetToSi(temperatureOffsetToSI) {}
public: public:
/*! /*!
* \brief Copy constructor * \brief Copy constructor
* \param otherUnit * \param otherUnit
*/ */
CTemperatureUnit(const CTemperatureUnit &otherUnit) : CMeasurementUnit(otherUnit) CTemperatureUnit(const CTemperatureUnit &otherUnit) : CMeasurementUnit(otherUnit), m_conversionOffsetToSi(otherUnit.m_conversionOffsetToSi) {}
/*!
* Assigment operator
*/
CTemperatureUnit &CTemperatureUnit::operator =(const CTemperatureUnit &otherUnit)
{ {
// void if (this == &otherUnit) return *this; // Same object? Yes, so skip assignment, and just return *this
CMeasurementUnit::operator = (otherUnit);
this->m_conversionOffsetToSi = otherUnit.m_conversionOffsetToSi;
return (*this);
} }
/*!
* \brief Convert to SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::convertToSiConversionUnit(double value) const;
/*!
* \brief Convert from SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::convertFromSiConversionUnit(double value) const;
/*! /*!
* \brief Kelvin * \brief Kelvin
* \return * \return
@@ -290,12 +338,13 @@ public:
* \brief Centigrade C * \brief Centigrade C
* \return * \return
*/ */
static const CTemperatureUnit& C() { static CTemperatureUnit C("centigrade", "°C", false, false);return C;} static const CTemperatureUnit& C() { static CTemperatureUnit C("centigrade", "°C", false, false, 1.0, 273.15);return C;}
/*! /*!
* \brief Fahrenheit F * \brief Fahrenheit F
* \return * \return
*/ */
static const CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0);return F;} static const CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0, 459.67);return F;}
}; };
/*! /*!
@@ -306,7 +355,7 @@ class CSpeedUnit : public CMeasurementUnit {
private: private:
/*! /*!
* Constructor * Constructor
* \brief CSpeedUnit * \brief Speed unit constructor
* \param name * \param name
* \param unitName * \param unitName
* \param isSIUnit * \param isSIUnit
@@ -320,7 +369,7 @@ private:
CMeasurementUnit(name, unitName, "speed", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {} CMeasurementUnit(name, unitName, "speed", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {}
public: public:
/*! /*!
* Downcast copy constructor, allows to implement methods in base class * Constructor, allows to implement methods in base class
* \param otherUnit * \param otherUnit
*/ */
CSpeedUnit(const CSpeedUnit &otherUnit) : CMeasurementUnit(otherUnit) {} CSpeedUnit(const CSpeedUnit &otherUnit) : CMeasurementUnit(otherUnit) {}
@@ -351,6 +400,59 @@ public:
static const CSpeedUnit& km_h() { static CSpeedUnit kmh("kilometer/hour", "km/h", false, false, 1.0/3.6, CMeasurementPrefix::One(), 1);return kmh;} static const CSpeedUnit& km_h() { static CSpeedUnit kmh("kilometer/hour", "km/h", false, false, 1.0/3.6, CMeasurementPrefix::One(), 1);return kmh;}
}; };
/*!
* Specialized class for time units (ms, hour, min).
* \author KWB
*/
class CTimeUnit : public CMeasurementUnit {
private:
/*!
* Constructor
* \brief Time unit constructor
* \param name
* \param unitName
* \param isSIUnit
* \param isSIBaseUnit
* \param conversionFactorToSI
* \param mulitplier
* \param displayDigits
* \param epsilon
*/
CTimeUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
CMeasurementUnit(name, unitName, "time", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon) {}
public:
/*!
* Constructor, allows to implement methods in base class
* \param otherUnit
*/
CTimeUnit(const CTimeUnit &otherUnit) : CMeasurementUnit(otherUnit) {}
/*!
* \brief Second s
* \return
*/
static const CTimeUnit& s() { static CTimeUnit s("second", "s", true, true, 1, CMeasurementPrefix::None(), 1); return s;}
/*!
* \brief Millisecond ms
* \return
*/
static const CTimeUnit& ms() { static CTimeUnit ms("millisecond", "ms", true, false, 1E-03, CMeasurementPrefix::m(), 0); return ms;}
/*!
* \brief Hour
* \return
*/
static const CTimeUnit& h() { static CTimeUnit h("hour", "h", false, false, 3600, CMeasurementPrefix::None(), 1); return h;}
/*!
* \brief Minute
* \return
*/
static const CTimeUnit& min() { static CTimeUnit min("minute", "min", false, false, 60, CMeasurementPrefix::None(), 2); return min;}
/*!
* \brief Day
* \return
*/
static const CTimeUnit& d() { static CTimeUnit day("day", "d", false, false, 3600*24, CMeasurementPrefix::None(), 1); return day;}
};
} // namespace } // namespace
#endif // PQUNITS_H #endif // PQUNITS_H

View File

@@ -93,9 +93,11 @@ void TestPhysicalQuantitiesBase::angleTests()
{ {
CAngle a1(180, CAngleUnit::deg()); CAngle a1(180, CAngleUnit::deg());
CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad()); CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad());
CAngle a3(35.4336,CAngleUnit::sexagesimalDeg()); // 35.72666
a2.switchUnit(CAngleUnit::deg()); a2.switchUnit(CAngleUnit::deg());
QVERIFY2(a2.unitValueToInteger() == 270, qPrintable(QString("1.5Pi should be 270deg, not %1 deg").arg(a2.unitValueToInteger()))); QVERIFY2(a2.unitValueToInteger() == 270, qPrintable(QString("1.5Pi should be 270deg, not %1 deg").arg(a2.unitValueToInteger())));
QVERIFY2(a1.piFactor() == 1, qPrintable(QString("Pi should be 1PI, not %1").arg(a1.piFactor()))); QVERIFY2(a1.piFactor() == 1, qPrintable(QString("Pi should be 1PI, not %1").arg(a1.piFactor())));
QVERIFY2(a3.valueRounded(CAngleUnit::deg()) == 35.73, "Expecting 35.73");
} }
/** /**
@@ -137,13 +139,24 @@ void TestPhysicalQuantitiesBase::temperatureTests()
CTemperature t1(0, CTemperatureUnit::C()); // 0C CTemperature t1(0, CTemperatureUnit::C()); // 0C
CTemperature t2(1, CTemperatureUnit::F()); // 1F CTemperature t2(1, CTemperatureUnit::F()); // 1F
CTemperature t3(220.15, CTemperatureUnit::F()); CTemperature t3(220.15, CTemperatureUnit::F());
CTemperature t4(10, CTemperatureUnit::F());
QVERIFY2(t1.convertedSiValueToDoubleRounded() == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.convertedSiValueToDoubleRounded()))); QVERIFY2(t1.convertedSiValueToDoubleRounded() == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.convertedSiValueToDoubleRounded())));
QVERIFY2(t2.valueRounded(CTemperatureUnit::C()) == -17.22, qPrintable(QString("1F shall be -17.22C, not %1 C").arg(t2.valueRounded(CTemperatureUnit::C())))); QVERIFY2(t2.valueRounded(CTemperatureUnit::C()) == -17.22, qPrintable(QString("1F shall be -17.22C, not %1 C").arg(t2.valueRounded(CTemperatureUnit::C()))));
QVERIFY2(t3.valueRounded(CTemperatureUnit::C()) == 104.53, qPrintable(QString("220.15F shall be 104.53C, not %1 C").arg(t3.valueRounded(CTemperatureUnit::C())))); QVERIFY2(t3.valueRounded(CTemperatureUnit::C()) == 104.53, qPrintable(QString("220.15F shall be 104.53C, not %1 C").arg(t3.valueRounded(CTemperatureUnit::C()))));
QVERIFY2(t4.valueRounded(CTemperatureUnit::K()) == 260.93, qPrintable(QString("10F shall be 260.93K, not %1 K").arg(t4.valueRounded(CTemperatureUnit::K()))));
} }
/** /**
* @brief Just testing obvious memory create / destruct flaws * Temperature tests
*/
void TestPhysicalQuantitiesBase::timeTests()
{
CTime t1(1, CTimeUnit::h());
QVERIFY2(t1.siBaseUnitValueToInteger() == 3600, "1hour shall be 3600s");
}
/**
* Just testing obvious memory create / destruct flaws
*/ */
void TestPhysicalQuantitiesBase::memoryTests() void TestPhysicalQuantitiesBase::memoryTests()
{ {

View File

@@ -52,6 +52,10 @@ private slots:
* \brief Testing temperature * \brief Testing temperature
*/ */
void temperatureTests(); void temperatureTests();
/*!
* \brief Testing time
*/
void timeTests();
/*! /*!
* \brief Testing construction / destruction in memory * \brief Testing construction / destruction in memory
*/ */