// scientific_units.cpp : Defines the entry point for the console application.
//
#include<iostream>
#include<string>
#include <sstream>
#include <iomanip>
using namespace std;
//internally for everything use SI units.
//mass in kilograms,
//time in seconds
//length in meters
template<int M, int L, int T>
class Quantity
{
public:
explicit Quantity(double val=0.0) : value(val){}
Quantity(const Quantity& x) : value(x.value)
{
}
Quantity& operator+=(const Quantity& rhs)
{
value+=rhs.value;
return *this;
}
Quantity& operator-=(const Quantity& rhs)
{
value-=rhs.value;
return *this;
}
double Convert(const Quantity& rhs)
{
return value/rhs.value;
}
///
/// Gets the value in SI units
///
double getValue() const
{
return value;
}
private:
double value;
};
template <int M, int L, int T>
Quantity<M,L,T> operator+(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return Quantity<M,L,T>(lhs)+=rhs;
}
template <int M, int L, int T>
Quantity<M,L,T> operator-(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return Quantity<M,L,T>(lhs)-=rhs;
}
template <int M1, int L1, int T1, int M2, int L2, int T2>
Quantity<M1+M2,L1+L2,T1+T2> operator*(const Quantity<M1,L1,T1>& lhs, const Quantity<M2,L2,T2>& rhs)
{
return Quantity<M1+M2,L1+L2,T1+T2>(lhs.getValue()*rhs.getValue());
}
template <int M, int L, int T>
Quantity<M,L,T> operator*(const double& lhs, const Quantity<M,L,T>& rhs)
{
return Quantity<M,L,T>(lhs*rhs.getValue());
}
template <int M1, int L1, int T1, int M2, int L2, int T2>
Quantity<M1-M2,L1-L2,T1-T2> operator/(const Quantity<M1,L1,T1>& lhs, const Quantity<M2,L2,T2>& rhs)
{
return Quantity<M1-M2,L1-L2,T1-T2>(lhs.getValue()/rhs.getValue());
}
template <int M, int L, int T>
Quantity<-M, -L, -T> operator/(double x, const Quantity<M,L,T>& rhs)
{
return Quantity<-M,-L,-T>(x/rhs.getValue());
}
template <int M, int L, int T>
Quantity<M, L, T> operator/(const Quantity<M,L,T>& rhs, double x)
{
return Quantity<M,L,T>(rhs.getValue()/x);
}
template <int M, int L, int T>
bool operator==(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return (lhs.getValue()==rhs.getValue());
}
template <int M, int L, int T>
bool operator!=(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return (lhs.getValue()!=rhs.getValue());
}
template <int M, int L, int T>
bool operator<=(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return lhs.getValue()<=rhs.getValue();
}
template <int M, int L, int T>
bool operator>=(const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return lhs.getValue()>=rhs.getValue();
}
template <int M, int L, int T>
bool operator< (const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return lhs.getValue()<rhs.getValue();
}
template <int M, int L, int T>
bool operator> (const Quantity<M,L,T>& lhs, const Quantity<M,L,T>& rhs)
{
return lhs.getValue()>rhs.getValue();
}
typedef Quantity<1,0,0> Mass;
typedef Quantity<0,1,0> Length;
typedef Quantity<0,2,0> Area;
typedef Quantity<0,3,0> Volume;
typedef Quantity<0,0,1> Time;
typedef Quantity<0,1,-1> Speed;
typedef Quantity<0,1,-2> Acceleration;
typedef Quantity<0,0,-1> Frequency;
//length units - verify the constants
const Length metre(1.0);
const Length decimetre = metre/10;
const Length centimetre = metre/100;
const Length millimetre = metre/1000;
const Length kilometre = 1000 * metre;
const Length inch = 2.54 * centimetre;
const Length foot = 12 * inch;
const Length yard = 3 * foot;
const Length mile = 5280 * foot;
const Frequency Hz(1.0);
const Area kilometre2 = kilometre*kilometre;
const Area metre2 = metre*metre;
const Area decimetre2 = decimetre*decimetre;
const Area centimetre2 = centimetre*centimetre;
const Area millimetre2 = millimetre * millimetre;
const Area inch2 =inch*inch;
const Area foot2 = foot*foot;
const Area mile2 = mile*mile;
const Volume kilometre3 = kilometre2*kilometre;
const Volume metre3 = metre2*metre;
const Volume decimetre3 = decimetre2*decimetre;
const Volume litre = decimetre3;
const Volume centimetre3 = centimetre2*centimetre;
const Volume millimetre3 = millimetre2 * millimetre;
const Volume inch3 =inch2*inch;
const Volume foot3 = foot2*foot;
const Volume mile3 = mile2*mile;
//time units
const Time second(1.0);
const Quantity<0,0,2> second2(1.0);
const Time minute = 60 * second;
const Time hour = 60 * minute;
const Time day = 24 * hour;
//mass units
const Mass kg(1.0);
const Mass gramme = 0.001 * kg;
const Mass tonne = 1000 * kg;
const Mass ounce = 0.028349523125 * kg;
const Mass pound = 16 * ounce;
const Mass stone = 14 * pound;
int main()
{
Length distance(100000*centimetre);
//Length distanceinFeet = distanceinCMs*convert(centimetre, foot);
std::cout << std::setprecision(15) << " 100000*centimetre = " << distance.Convert(foot) << " feet" << std::endl;
//get in terms of miles and feet
double total_in_miles = distance.Convert(mile);
double total_in_feet = distance.Convert(foot);
cout << total_in_miles << " miles" << endl;
cout << total_in_feet << " feet" << endl;
std::cout << " 1 foot = " << (1*foot).Convert(centimetre) << " cm" << std::endl;
Length distance100 = 100*kilometre;
Time time = 2*hour;
Speed sp1 = distance100 / time; // metre/second
cout << "100 km in 2 hours: " << sp1.Convert(kilometre/hour) << " km/hour" << endl;
cout << "100 km in 2 hours: " << sp1.Convert(mile/hour) << " mile/hour" << endl;
Frequency fr1 = 100*Hz;
Time interval = 1/fr1;
cout << "frequency (1/s): " << fr1.Convert(Hz) << endl;
cout << "interval (s): " << interval.Convert(second) << endl;
Acceleration a1 = 9.8*metre/(second*second);
cout << "accelaration (m/s2): " << a1.Convert(metre/(second*second)) << endl;
Length distance2 = 1*mile;
cout << "1 mile: " << distance2.Convert(metre) << " metres" << endl;
Mass myMass = 80*kg;
cout << "my mass: " << myMass.Convert(kg) << " kg" << endl;
cout << "my mass: " << myMass.Convert(stone) << " stone" << endl;
cout << "my mass: " << myMass.Convert(pound) << " pounds" << endl;
Mass onePound = 1*pound;
cout << "one pound in grammes: " << std::setprecision(15) << onePound.Convert(gramme) << endl;
cout << "one pound in kg: " << onePound.Convert(kg) << endl;
cout << "one pound in ounces: " << onePound.Convert(ounce) << endl;
std::cout << "20 miles = " << (20 * mile).Convert(metre) << " metres" << std::endl;
std::cout << "20 miles = " << (20 * mile).Convert(kilometre) << " kilometres" << std::endl;
std::cout << "20 miles = " << (20 * mile).Convert(yard) << " yards" << std::endl;
std::cout << "100 inches = " << (100.0 * inch).Convert(mile) << " miles" << std::endl;
std::cout << "299792458 metres per second = " << (299792458.0 * metre/second).Convert(kilometre/hour) << " km/h" << std::endl;
std::cout << "299792458 metres per second = " << (299792458.0 * metre/second).Convert(mile/hour) << " miles/h" << std::endl;
std::cout << "3.5 hours * 3 miles/hour = " << ((3.5 * hour) * (3.0 * mile/hour)).Convert(mile) << " miles" << std::endl;
std::cout << "(3.5 metres/s) / (2 sec) = " << ((3.5 * metre/second) / (2 * second)).Convert(metre/second2) << " m/s2" << std::endl;
return 0;
}