File indexing completed on 2024-05-12 05:55:19

0001 // This file is part of the SpeedCrunch project
0002 // Copyright (C) 2015 Pol Welter <polwelter@gmail.com>
0003 // Copyright (C) 2016 @heldercorreia
0004 //
0005 // This program is free software; you can redistribute it and/or
0006 // modify it under the terms of the GNU General Public License
0007 // as published by the Free Software Foundation; either version 2
0008 // of the License, or (at your option) any later version.
0009 //
0010 // This program is distributed in the hope that it will be useful,
0011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 // GNU General Public License for more details.
0014 //
0015 // You should have received a copy of the GNU General Public License
0016 // along with this program; see the file COPYING.  If not, write to
0017 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018 // Boston, MA 02110-1301, USA.
0019 
0020 #include "units.h"
0021 
0022 #include "quantity.h"
0023 #include "rational.h"
0024 
0025 #include <QLocale>
0026 #include <QString>
0027 #include <QStringList>
0028 
0029 // TODO: find out how to get gettext to recognize these (or write a xgettext
0030 // replacement that actually supports C++ properly...)
0031 #define UNIT_CACHE(name, value) \
0032     const Quantity Units::name() \
0033     { \
0034         if (!m_cache.contains(#name)) \
0035             m_cache[#name] = value; \
0036         return (m_cache[#name]); \
0037     }
0038 
0039 #define BASE_UNIT_CACHE(name, dimension) \
0040     const Quantity Units::name() \
0041     { \
0042         if (!m_cache.contains(#name)) { \
0043             Quantity name(1); \
0044             name.modifyDimension(dimension, 1); \
0045             m_cache[#name] = name; \
0046         } \
0047         return m_cache[#name]; \
0048     }
0049 
0050 QHash<QMap<QString, Rational>, Unit> Units::m_matchLookup;
0051 QMap<QString, Quantity> Units::m_cache;
0052 
0053 
0054 void Units::pushUnit(Quantity q, QString name)
0055 {
0056     q.cleanDimension();
0057     Unit u(name, q);
0058     m_matchLookup.insert(q.getDimension(), u);
0059 }
0060 
0061 unsigned int qHash(QMap<QString, Rational> dimension)
0062 {
0063     QStringList keyList(dimension.keys());
0064     QString blob("");
0065     keyList.sort();
0066     for (int i = 0; i < keyList.size(); ++i) {
0067         keyList[i].append(dimension[keyList[i]].toString());
0068         blob.append(keyList[i]);
0069     }
0070     return qHash(blob);
0071 }
0072 
0073 /*
0074  * initialize the lookup table for automatic matching
0075  */
0076 void Units::initTable()
0077 {
0078     m_matchLookup.clear();
0079     pushUnit(joule(), "newton meter");                          // energy or torque
0080     pushUnit(newton(), "newton");                               // force
0081     pushUnit(watt(), "watt");                                   // power
0082     pushUnit(pascal(), "pascal");                               // pressure or energy density
0083     pushUnit(coulomb(), "coulomb");                             // charge
0084     pushUnit(volt(), "volt");                                   // electrical potential
0085     pushUnit(ohm(), "ohm");                                     // el. resistance
0086     pushUnit(siemens(), "siemens");                             // el. conductance
0087     pushUnit(ohm()*meter(), "ohm meter");                       // el. resistivity
0088     pushUnit(siemens()/meter(), "siemens/meter");               // el. conductivity
0089     pushUnit(siemens()/meter()/mole(), "siemens/(meter mole)"); // molar conductivity
0090     pushUnit(farad(), "farad");                                 // capacitance
0091     pushUnit(tesla(), "tesla");                                 // magnetic flux density
0092     pushUnit(weber(), "weber");                                 // magnetic flux
0093     pushUnit(henry(), "henry");                                 // inductance
0094     pushUnit(coulomb()/cbmeter(), "coulomb/meter³");            // electric charge density
0095     pushUnit(coulomb()/sqmeter(), "coulomb/meter²");            // surface charge density or el. flux
0096     pushUnit(coulomb()/kilogram(), "coulomb/kilogram");         // exposure
0097     pushUnit(farad()/meter(), "farad/meter");                   // permittivity
0098     pushUnit(henry()/meter(), "henry/meter");                   // permeability
0099     pushUnit(joule()/kilogram()/kelvin(),"joule/(kilogram kelvin)");    // specific heat capacity
0100     pushUnit(joule()/mole()/kelvin(), "joule/(mole kelvin");            // molar heat capacity
0101     pushUnit(mole()/second()/cbmeter(), "mole/(second meter³)");        // catalytic activity
0102     pushUnit(newton()/meter(), "newton/meter");                 // surface tension
0103     pushUnit(pascal()*second(), "pascal second");               // dynamic viscosity
0104     pushUnit(volt()/meter(), "volt/meter");                     // el. field
0105     pushUnit(watt()/meter()/kelvin(), "watt/(meter kelvin)");   // thermal conductivity
0106     pushUnit(watt()/sqmeter(), "watt/meter²");                  // heat flux
0107     pushUnit(joule()/kelvin(), "joule/kelvin");                 // entropy or heat capacity
0108     pushUnit(joule()/kilogram(), "joule/kilogram");             // specific energy
0109 }
0110 
0111 void Units::findUnit(Quantity& q)
0112 {
0113     QString unit_name = "";
0114     CNumber unit(1);
0115     q.cleanDimension();
0116 
0117     if (m_matchLookup.isEmpty())
0118         initTable();
0119 
0120     // Match derived units.
0121     if (m_matchLookup.contains(q.getDimension())) {
0122         Unit temp(m_matchLookup[q.getDimension()]);
0123         q.setDisplayUnit(temp.value.numericValue(), temp.name);
0124     } else {
0125         // Autogenerate unit name (product of base units).
0126         QMap<QString, Rational> dimension = q.getDimension();
0127         QMap<QString, Rational>::const_iterator i = dimension.constBegin();
0128         while (i != dimension.constEnd()) {
0129             QString exponent = i.value().toString();
0130             if (exponent.contains('/'))
0131                 exponent = "^(" + exponent+')';
0132             else if (exponent == "1")
0133                 exponent = "";
0134             else
0135                 exponent = '^' + exponent;
0136 
0137             if (exponent == QLatin1String("^0")) exponent = QString::fromUtf8("⁰");
0138             else if (exponent == QLatin1String("^2")) exponent = QString::fromUtf8("²");
0139             else if (exponent == QLatin1String("^3")) exponent = QString::fromUtf8("³");
0140             else if (exponent == QLatin1String("^4")) exponent = QString::fromUtf8("⁴") ;
0141             else if (exponent == QLatin1String("^5")) exponent = QString::fromUtf8("⁵") ;
0142             else if (exponent == QLatin1String("^6")) exponent = QString::fromUtf8("⁶") ;
0143             else if (exponent == QLatin1String("^7")) exponent = QString::fromUtf8("⁷") ;
0144             else if (exponent == QLatin1String("^8")) exponent = QString::fromUtf8("⁸") ;
0145             else if (exponent == QLatin1String("^9")) exponent = QString::fromUtf8("⁹") ;
0146             else if (exponent == QLatin1String("^-1")) exponent = QString::fromUtf8("⁻¹");
0147             else if (exponent == QLatin1String("^-2")) exponent = QString::fromUtf8("⁻²");
0148             else if (exponent == QLatin1String("^-3")) exponent = QString::fromUtf8("⁻³");
0149             else if (exponent == QLatin1String("^-4")) exponent = QString::fromUtf8("⁻⁴") ;
0150             else if (exponent == QLatin1String("^-5")) exponent = QString::fromUtf8("⁻⁵") ;
0151             else if (exponent == QLatin1String("^-6")) exponent = QString::fromUtf8("⁻⁶") ;
0152             else if (exponent == QLatin1String("^-7")) exponent = QString::fromUtf8("⁻⁷") ;
0153             else if (exponent == QLatin1String("^-8")) exponent = QString::fromUtf8("⁻⁸") ;
0154             else if (exponent == QLatin1String("^-9")) exponent = QString::fromUtf8("⁻⁹") ;
0155 
0156             // TODO: Replace this with a lookup to a repository.
0157             if (i.key() == "length")
0158                 unit_name += " meter";
0159             else if (i.key() == "time")
0160                 unit_name += " second";
0161             else if (i.key() == "mass")
0162                 unit_name += " kilogram";
0163             else if (i.key() == "el. current")
0164                 unit_name += " ampere";
0165             else if (i.key() == "amount")
0166                 unit_name += " mole";
0167             else if (i.key() == "luminous intensity")
0168                 unit_name += " candela";
0169             else if (i.key() == "temperature")
0170                 unit_name += " kelvin";
0171             else if (i.key() == "information") {
0172                 unit_name += " bit";
0173             } else
0174                 unit_name += " " + i.key(); // fall back to the dimension name
0175             unit_name += exponent;
0176             ++i;
0177         }
0178         q.setDisplayUnit(unit, unit_name.trimmed());
0179     }
0180 }
0181 
0182 #define ADD_UNIT(name) result.append(Unit(#name, name()))
0183 #define ADD_UNIT_ALIAS(name, alias) result.append(Unit(#alias, name()))
0184 
0185 // This list contains the units that wil be set as builtin variables by the evaluator.
0186 const QList<Unit> Units::getList()
0187 {
0188     QList<Unit> result;
0189 
0190     ADD_UNIT(meter);
0191     ADD_UNIT_ALIAS(meter, meters);
0192     ADD_UNIT(second);
0193     ADD_UNIT_ALIAS(second, seconds);
0194     ADD_UNIT(kilogram);
0195     ADD_UNIT_ALIAS(kilogram, kilograms);
0196     ADD_UNIT(ampere);
0197     ADD_UNIT_ALIAS(ampere, amperes);
0198     ADD_UNIT(mole);
0199     ADD_UNIT(candela);
0200     ADD_UNIT(kelvin);
0201     ADD_UNIT(bit);
0202 
0203     ADD_UNIT(yocto);
0204     ADD_UNIT(zepto);
0205     ADD_UNIT(atto);
0206     ADD_UNIT(femto);
0207     ADD_UNIT(pico);
0208     ADD_UNIT(nano);
0209     ADD_UNIT(micro);
0210     ADD_UNIT(milli);
0211     ADD_UNIT(centi);
0212     ADD_UNIT(deci);
0213     ADD_UNIT(deca);
0214     ADD_UNIT(hecto);
0215     ADD_UNIT(kilo);
0216     ADD_UNIT(mega);
0217     ADD_UNIT(giga);
0218     ADD_UNIT(tera);
0219     ADD_UNIT(peta);
0220     ADD_UNIT(exa);
0221     ADD_UNIT(zetta);
0222     ADD_UNIT(yotta);
0223     ADD_UNIT(kibi);
0224     ADD_UNIT(mebi);
0225     ADD_UNIT(gibi);
0226     ADD_UNIT(tebi);
0227     ADD_UNIT(pebi);
0228     ADD_UNIT(exbi);
0229     ADD_UNIT(zebi);
0230     ADD_UNIT(yobi);
0231 
0232     ADD_UNIT(sqmeter);
0233     ADD_UNIT(cbmeter);
0234     ADD_UNIT(newton);
0235     ADD_UNIT(hertz);
0236     ADD_UNIT(joule);
0237     ADD_UNIT(watt);
0238     ADD_UNIT(pascal);
0239     ADD_UNIT(coulomb);
0240     ADD_UNIT(volt);
0241     ADD_UNIT(ohm);
0242     ADD_UNIT(farad);
0243     ADD_UNIT(tesla);
0244     ADD_UNIT(weber);
0245     ADD_UNIT(henry);
0246     ADD_UNIT(siemens);
0247     ADD_UNIT(becquerel);
0248     ADD_UNIT(gray);
0249     ADD_UNIT(sievert);
0250     ADD_UNIT(katal);
0251     ADD_UNIT(steradian);
0252     ADD_UNIT(lumen);
0253     ADD_UNIT(lux);
0254 
0255     ADD_UNIT(metric_ton);
0256     ADD_UNIT(short_ton);
0257     ADD_UNIT(long_ton);
0258     ADD_UNIT(pound);
0259     ADD_UNIT(ounce);
0260     ADD_UNIT(grain);
0261     ADD_UNIT(gram);
0262     ADD_UNIT(atomic_mass_unit);
0263     ADD_UNIT(carat);
0264 
0265     ADD_UNIT(micron);
0266     ADD_UNIT(angstrom);
0267     ADD_UNIT(astronomical_unit);
0268     ADD_UNIT(lightyear);
0269     ADD_UNIT(lightsecond);
0270     ADD_UNIT(lightminute);
0271     ADD_UNIT(parsec);
0272     ADD_UNIT(inch);
0273     ADD_UNIT(foot);
0274     ADD_UNIT_ALIAS(foot, feet);
0275     ADD_UNIT(yard);
0276     ADD_UNIT_ALIAS(yard, yards);
0277     ADD_UNIT(mile);
0278     ADD_UNIT_ALIAS(mile, miles);
0279     ADD_UNIT(rod);
0280     ADD_UNIT(furlong);
0281     ADD_UNIT(fathom);
0282     ADD_UNIT(nautical_mile);
0283     ADD_UNIT(cable);
0284 
0285     ADD_UNIT(UK_gallon);
0286     ADD_UNIT(US_gallon);
0287     ADD_UNIT_ALIAS(US_gallon, gallon_US);
0288     ADD_UNIT_ALIAS(UK_gallon, gallon_UK);
0289     ADD_UNIT_ALIAS(UK_gallon, imperial_gallon);
0290     ADD_UNIT(UK_quart);
0291     ADD_UNIT(US_quart);
0292     ADD_UNIT_ALIAS(US_quart, quart_US);
0293     ADD_UNIT_ALIAS(UK_quart, quart_UK);
0294     ADD_UNIT(UK_pint);
0295     ADD_UNIT(US_pint);
0296     ADD_UNIT_ALIAS(US_pint, pint_US);
0297     ADD_UNIT_ALIAS(UK_pint, pint_UK);
0298     ADD_UNIT(UK_fluid_ounce);
0299     ADD_UNIT(US_fluid_ounce);
0300     ADD_UNIT_ALIAS(US_fluid_ounce, us_fl_oz);
0301     ADD_UNIT_ALIAS(US_fluid_ounce, us_floz);
0302     ADD_UNIT_ALIAS(US_fluid_ounce, fluid_ounce_US);
0303     ADD_UNIT_ALIAS(UK_fluid_ounce, uk_fl_oz);
0304     ADD_UNIT_ALIAS(UK_fluid_ounce, uk_floz);
0305     ADD_UNIT_ALIAS(UK_fluid_ounce, fluid_ounce_UK);
0306     ADD_UNIT(liter);
0307     ADD_UNIT_ALIAS(liter, litre);
0308     ADD_UNIT_ALIAS(liter, liters);
0309     ADD_UNIT_ALIAS(liter, litres);
0310 
0311     // Time
0312     ADD_UNIT(minute);
0313     ADD_UNIT_ALIAS(minute, minutes);
0314 
0315     ADD_UNIT(hour);
0316     ADD_UNIT_ALIAS(hour,   hours);
0317     ADD_UNIT_ALIAS(hour,   h); // so sue me
0318 
0319     ADD_UNIT(day);
0320     ADD_UNIT_ALIAS(day,    days);
0321 
0322     ADD_UNIT(week);
0323     ADD_UNIT_ALIAS(week,   weeks);
0324 
0325     ADD_UNIT(julian_year);
0326     ADD_UNIT(tropical_year);
0327     ADD_UNIT(sidereal_year);
0328     ADD_UNIT_ALIAS(julian_year, year_julian);
0329     ADD_UNIT_ALIAS(tropical_year, year_tropical);
0330     ADD_UNIT_ALIAS(sidereal_year, year_sidereal);
0331 
0332     ADD_UNIT(percent);
0333     ADD_UNIT(ppm);
0334     ADD_UNIT(ppb);
0335     ADD_UNIT(karat);
0336 
0337     ADD_UNIT(bar);
0338     ADD_UNIT(atmosphere);
0339     ADD_UNIT(torr);
0340     ADD_UNIT(pounds_per_sqinch);
0341 
0342     ADD_UNIT(electron_volt);
0343     ADD_UNIT(calorie);
0344     ADD_UNIT(british_thermal_unit);
0345 
0346     ADD_UNIT(nat);
0347     ADD_UNIT(hartley);
0348     ADD_UNIT(byte);
0349     ADD_UNIT_ALIAS(byte, bytes);
0350 
0351     ADD_UNIT(exabyte);
0352     ADD_UNIT(terabyte);
0353     ADD_UNIT(gigabyte);
0354     ADD_UNIT(megabyte);
0355     ADD_UNIT(kilobyte);
0356     ADD_UNIT_ALIAS(exabyte, exabytes);
0357     ADD_UNIT_ALIAS(terabyte, terabytes);
0358     ADD_UNIT_ALIAS(gigabyte, gigabytes);
0359     ADD_UNIT_ALIAS(megabyte, megabytes);
0360     ADD_UNIT_ALIAS(kilobyte, kilobytes);
0361 
0362     ADD_UNIT(exbibyte);
0363     ADD_UNIT(tebibyte);
0364     ADD_UNIT(gibibyte);
0365     ADD_UNIT(mebibyte);
0366     ADD_UNIT(kibibyte);
0367     ADD_UNIT_ALIAS(exbibyte, exbibytes);
0368     ADD_UNIT_ALIAS(tebibyte, tebibytes);
0369     ADD_UNIT_ALIAS(gibibyte, gibibytes);
0370     ADD_UNIT_ALIAS(mebibyte, mebibytes);
0371     ADD_UNIT_ALIAS(kibibyte, kibibytes);
0372     ADD_UNIT_ALIAS(exbibyte, eb);
0373     ADD_UNIT_ALIAS(tebibyte, tb);
0374     ADD_UNIT_ALIAS(gibibyte, gb);
0375     ADD_UNIT_ALIAS(mebibyte, mb);
0376     ADD_UNIT_ALIAS(kibibyte, kb);
0377 
0378     ADD_UNIT(bps);
0379     ADD_UNIT(tbps);
0380     ADD_UNIT(gbps);
0381     ADD_UNIT(mbps);
0382     ADD_UNIT(kbps);
0383 
0384     ADD_UNIT(tablespoon);
0385     ADD_UNIT_ALIAS(tablespoon, tablespoons);
0386     ADD_UNIT(teaspoon);
0387     ADD_UNIT_ALIAS(teaspoon, teaspoons);
0388     ADD_UNIT(cup);
0389     ADD_UNIT_ALIAS(cup, cups);
0390 
0391     ADD_UNIT(gravity);
0392     ADD_UNIT_ALIAS(gravity, force);
0393     ADD_UNIT(speed_of_light);
0394     ADD_UNIT(speed_of_sound_STP);
0395     ADD_UNIT(elementary_charge);
0396     ADD_UNIT(knot);
0397     ADD_UNIT(horsepower);
0398 
0399     switch(QLocale::system().measurementSystem()) {
0400     case QLocale::ImperialUSSystem:
0401         ADD_UNIT_ALIAS(US_pint, pint);
0402         ADD_UNIT_ALIAS(US_gallon, gallon);
0403         ADD_UNIT_ALIAS(US_quart, quart);
0404         ADD_UNIT_ALIAS(US_pint, pint);
0405         ADD_UNIT_ALIAS(US_fluid_ounce, fl_oz);
0406         ADD_UNIT_ALIAS(US_fluid_ounce, floz);
0407         break;
0408     case QLocale::ImperialUKSystem:
0409         ADD_UNIT_ALIAS(UK_pint, pint);
0410         ADD_UNIT_ALIAS(UK_gallon, gallon);
0411         ADD_UNIT_ALIAS(UK_quart, quart);
0412         ADD_UNIT_ALIAS(UK_pint, pint);
0413         ADD_UNIT_ALIAS(UK_fluid_ounce, fl_oz);
0414         ADD_UNIT_ALIAS(UK_fluid_ounce, floz);
0415         break;
0416     default:
0417         break;
0418     }
0419 
0420     return result;
0421 }
0422 
0423 BASE_UNIT_CACHE(meter, "length")
0424 BASE_UNIT_CACHE(second, "time")
0425 BASE_UNIT_CACHE(kilogram, "mass")
0426 BASE_UNIT_CACHE(ampere, "el. current")
0427 BASE_UNIT_CACHE(mole, "amount")
0428 BASE_UNIT_CACHE(kelvin, "temperature")
0429 BASE_UNIT_CACHE(candela, "luminous intensity")
0430 BASE_UNIT_CACHE(bit, "information")
0431 
0432 UNIT_CACHE(yocto, HNumber("1e-24"))
0433 UNIT_CACHE(zepto, HNumber("1e-21"))
0434 UNIT_CACHE(atto, HNumber("1e-18"))
0435 UNIT_CACHE(femto, HNumber("1e-15"))
0436 UNIT_CACHE(pico, HNumber("1e-12"))
0437 UNIT_CACHE(nano, HNumber("1e-9"))
0438 UNIT_CACHE(micro, HNumber("1e-6"))
0439 UNIT_CACHE(milli, HNumber("1e-3"))
0440 UNIT_CACHE(centi, HNumber("1e-2"))
0441 UNIT_CACHE(deci, HNumber("1e-1"))
0442 
0443 UNIT_CACHE(deca, HNumber("1e1"))
0444 UNIT_CACHE(hecto, HNumber("1e2"))
0445 UNIT_CACHE(kilo, HNumber("1e3"))
0446 UNIT_CACHE(mega, HNumber("1e6"))
0447 UNIT_CACHE(giga, HNumber("1e9"))
0448 UNIT_CACHE(tera, HNumber("1e12"))
0449 UNIT_CACHE(peta, HNumber("1e15"))
0450 UNIT_CACHE(exa, HNumber("1e18"))
0451 UNIT_CACHE(zetta, HNumber("1e21"))
0452 UNIT_CACHE(yotta, HNumber("1e24"))
0453 
0454 UNIT_CACHE(kibi, HNumber("1024"))
0455 UNIT_CACHE(mebi, kibi()*kibi())
0456 UNIT_CACHE(gibi, kibi()*mebi())
0457 UNIT_CACHE(tebi, kibi()*gibi())
0458 UNIT_CACHE(pebi, kibi()*tebi())
0459 UNIT_CACHE(exbi, kibi()*pebi())
0460 UNIT_CACHE(zebi, kibi()*exbi())
0461 UNIT_CACHE(yobi, kibi()*zebi())
0462 
0463 UNIT_CACHE(newton,              meter() * kilogram() / (second()*second()))
0464 UNIT_CACHE(hertz,               Quantity(1) / second())
0465 UNIT_CACHE(pascal,              newton() / sqmeter())
0466 UNIT_CACHE(joule,               newton() * meter())
0467 UNIT_CACHE(watt,                joule() / second())
0468 UNIT_CACHE(coulomb,             ampere() * second())
0469 UNIT_CACHE(volt,                watt() / ampere())
0470 UNIT_CACHE(farad,               coulomb() / volt())
0471 UNIT_CACHE(ohm,                 volt() / ampere())
0472 UNIT_CACHE(siemens,             ampere() / volt())
0473 UNIT_CACHE(weber,               volt() * second())
0474 UNIT_CACHE(tesla,               weber() / sqmeter())
0475 UNIT_CACHE(henry,               weber() / ampere())
0476 UNIT_CACHE(becquerel,           Quantity(1) / second())
0477 UNIT_CACHE(gray,                joule() / kilogram())
0478 UNIT_CACHE(sievert,             joule() / kilogram())
0479 UNIT_CACHE(katal,               mole() / second())
0480 UNIT_CACHE(steradian,           1)
0481 UNIT_CACHE(lumen,               candela()*steradian())
0482 UNIT_CACHE(lux,                 lumen()/sqmeter())
0483 
0484 UNIT_CACHE(sqmeter,             meter() * meter())
0485 UNIT_CACHE(cbmeter,             sqmeter() * meter())
0486 
0487 UNIT_CACHE(metric_ton,          mega()*gram())
0488 UNIT_CACHE(gram,                milli()*kilogram())
0489 UNIT_CACHE(pound,               HNumber("0.45359237") * kilogram())
0490 UNIT_CACHE(ounce,               pound() / HNumber(16))
0491 UNIT_CACHE(grain,               pound() / HNumber(7000))
0492 UNIT_CACHE(short_ton,           HNumber(2000) * pound())
0493 UNIT_CACHE(long_ton,            HNumber(2240) * pound())
0494 UNIT_CACHE(atomic_mass_unit,    HNumber("1.660539040e-27") * kilogram()) // http://physics.nist.gov/cgi-bin/cuu/Value?tukg
0495 UNIT_CACHE(carat,               HNumber(200) * milli()*gram()) // Do not confuse with karat below.
0496 
0497 UNIT_CACHE(micron,              micro()*meter())
0498 UNIT_CACHE(angstrom,            HNumber("1e-10") * meter())
0499 UNIT_CACHE(astronomical_unit,   HNumber("149597870700") * meter()) // IAU 2012 Resolution B2.
0500 UNIT_CACHE(lightyear,           speed_of_light() * julian_year())
0501 UNIT_CACHE(lightminute,         speed_of_light() * minute())
0502 UNIT_CACHE(lightsecond,         speed_of_light() * second())
0503 UNIT_CACHE(parsec,              HNumber(648000)/HMath::pi() * astronomical_unit()) // IAU 2015 Resolution B2.
0504 UNIT_CACHE(inch,                HNumber("0.0254") * meter()) // International inch.
0505 UNIT_CACHE(foot,                HNumber(12) * inch())
0506 UNIT_CACHE(yard,                HNumber(36) * inch())
0507 UNIT_CACHE(mile,                HNumber(1760) * yard())
0508 UNIT_CACHE(rod,                 HNumber("5.5") * yard())
0509 UNIT_CACHE(furlong,             HNumber(40) * rod())
0510 UNIT_CACHE(fathom,              HNumber(6) * foot())
0511 UNIT_CACHE(nautical_mile,       HNumber("1852") * meter())
0512 UNIT_CACHE(cable,               HNumber("0.1") * nautical_mile())
0513 
0514 UNIT_CACHE(are,                 HNumber(100) * sqmeter())
0515 UNIT_CACHE(hectare,             HNumber(100) * are())
0516 UNIT_CACHE(acre,                mile()*mile() / HNumber(640))
0517 
0518 UNIT_CACHE(US_gallon,           HNumber("3.785") * liter())
0519 UNIT_CACHE(UK_gallon,           HNumber("4.54609") * liter())
0520 UNIT_CACHE(US_quart,            US_gallon() / HNumber(4))
0521 UNIT_CACHE(UK_quart,            UK_gallon() / HNumber(4))
0522 UNIT_CACHE(US_pint,             US_gallon() / HNumber(8))
0523 UNIT_CACHE(UK_pint,             UK_gallon() / HNumber(8))
0524 UNIT_CACHE(US_fluid_ounce,      US_gallon() / HNumber(128))
0525 UNIT_CACHE(UK_fluid_ounce,      UK_gallon() / HNumber(160))
0526 UNIT_CACHE(liter,               milli() * cbmeter())
0527 
0528 
0529 UNIT_CACHE(minute,              HNumber(60) * second())
0530 UNIT_CACHE(hour,                HNumber(60) * minute())
0531 UNIT_CACHE(day,                 HNumber(24) * hour())
0532 UNIT_CACHE(week,                HNumber(7) * day())
0533 UNIT_CACHE(julian_year,         HNumber("365.25") * day())
0534 UNIT_CACHE(tropical_year,       HNumber("365.24219") * day()) // Approx.: changes over time due to Earth's precession.
0535 UNIT_CACHE(sidereal_year,       HNumber("365.25636") * day()) // http://hpiers.obspm.fr/eop-pc/models/constants.html
0536 
0537 UNIT_CACHE(percent,             HNumber("0.01"))
0538 UNIT_CACHE(ppm,                 HNumber("1e-6"))
0539 UNIT_CACHE(ppb,                 HNumber("1e-9"))
0540 UNIT_CACHE(karat,               Rational(1,24).toHNumber()) // Do not confuse with carat above.
0541 
0542 UNIT_CACHE(bar,                 HNumber("1e5") * pascal())
0543 UNIT_CACHE(atmosphere,          HNumber("1.01325") * bar())
0544 UNIT_CACHE(torr,                atmosphere() / HNumber(760))
0545 UNIT_CACHE(pounds_per_sqinch,   pound() * gravity() / (inch()*inch()))
0546 
0547 UNIT_CACHE(electron_volt,       elementary_charge() * volt())
0548 UNIT_CACHE(calorie,             HNumber("4.1868") * joule()) // International Table calorie.
0549 UNIT_CACHE(british_thermal_unit, HNumber("1055.056") * joule()) // International standard ISO 31-4.
0550 
0551 UNIT_CACHE(nat,                 bit() / HMath::ln(2))
0552 UNIT_CACHE(hartley,             HMath::ln(10) * nat())
0553 UNIT_CACHE(byte,                HNumber(8) * bit())
0554 
0555 UNIT_CACHE(exbibyte,            exbi() * byte())
0556 UNIT_CACHE(tebibyte,            tebi() * byte())
0557 UNIT_CACHE(gibibyte,            gibi() * byte())
0558 UNIT_CACHE(mebibyte,            mebi() * byte())
0559 UNIT_CACHE(kibibyte,            kibi() * byte())
0560 
0561 UNIT_CACHE(bps,                 bit() / second())
0562 UNIT_CACHE(tbps,                tebi() * bps())
0563 UNIT_CACHE(gbps,                gibi() * bps())
0564 UNIT_CACHE(mbps,                mebi() * bps())
0565 UNIT_CACHE(kbps,                kibi() * bps())
0566 
0567 UNIT_CACHE(exabyte,             exa()  * HNumber(8) * bit())
0568 UNIT_CACHE(terabyte,            tera() * HNumber(8) * bit())
0569 UNIT_CACHE(gigabyte,            giga() * HNumber(8) * bit())
0570 UNIT_CACHE(megabyte,            mega() * HNumber(8) * bit())
0571 UNIT_CACHE(kilobyte,            kilo() * HNumber(8) * bit())
0572 
0573 UNIT_CACHE(tablespoon,          HNumber(15) * milli()*liter())
0574 UNIT_CACHE(teaspoon,            HNumber(5) * milli()*liter())
0575 UNIT_CACHE(cup,                 HNumber(240) * milli()*liter())
0576 
0577 UNIT_CACHE(gravity,             HNumber("9.80665") * newton() / kilogram()) // 3rd CGPM (1901, CR 70).
0578 UNIT_CACHE(speed_of_light,      HNumber(299792458) * meter() / second())
0579 UNIT_CACHE(elementary_charge,   HNumber("1.6021766208e-19") * coulomb()) // http://physics.nist.gov/cgi-bin/cuu/Value?e
0580 UNIT_CACHE(speed_of_sound_STP,  HNumber(331) * meter()/second())
0581 UNIT_CACHE(knot,                nautical_mile()/hour())
0582 UNIT_CACHE(horsepower,          HNumber(550) * foot() * pound() * gravity() / second()) // Imperial horsepower.