[boost.units] Parser für Einheiten
-
Hallo zusammen
Für eine Erweiterung in meinem Programm bräuchte ich eine Funktionalität ähnlich wie angeboten in JScience:
http://jscience.org/jsr-275/api/javax/measure/unit/UnitFormat.htmlEs geht z.B. darum, dass ich einen textuellen Input von "900000*Ws" bekomme und diesen in "0.25*kWh" umwandeln muss. Das natürlich auch für eine Serie anderer physikalischer Einheiten, wie etwa "m^3". Boost Units bietet diese Umrechnungs-Funktionalität, ist aber sehr Compile-Time-Check lastig, weshalb diese Parse-Funktion vermutlich auch nicht vorimplementiert ist.
Gibt es eine Variante, das mit vernünftigem Aufwand in C++ zu implementieren? Gibt es dazu eventuell passende, Runtime-checked Libraries?
Danke für Vorschläge und Gruss
Kessi
-
Ich weiß nicht ob es ganz das ist, was du möchtest, aber vielleicht kannst du hiermit etwas anfangen.
-
@ DerKuchen: Hey, das muss ich mir mal genauer anschauen! Habe letztens für eines meiner Projekte etwas ähnliches programmoratisiert (dynamisch einheiten laden, nach dynamisch geladenen algebraischen Regeln vereinfachen etc.). Aber ich hatte irgendwann das Problem, die Muster gegen Sequenzen von "gleichgestellten" (weil kommutativen) Operationen zu matchen, müsste mal raussuchen, was genau das Problem war und bei dir vergleichen^^
-
DerKuchen schrieb:
Ich weiß nicht ob es ganz das ist, was du möchtest, aber vielleicht kannst du hiermit etwas anfangen.
Besten Dank schon mal. Das sieht zwar sehr vielversprechend aus, ist aber noch nicht wirklich einsatzbereit. So gibt es z.B. keine Variante, Watt anders darzustellen als "200 m^2 kg s^-3". Ausserdem fehlt mir eine Konvertierungsfunktion, z.B. von Ws zu kWh.
Die Features, die mir wichtig wären, sind Konvertierung (Ws => kWh) und interpretieren von Strings (z.B. "75 Ws" einlesen).
-
Kessi, auf den ersten Blick machte es mir den Eindruck, als könnte man die Einheiten leicht erweitern... und um den Umrechnungsfaktor zu bekommen, brauchst du die beiden ja nur durcheinander teilen, ich meine auch sowas dort gesehen zu haben.
-
Ich bin zwar sehr überrascht, muss dir aber Recht geben. Die Library ist zwar äusserst kompakt, bietet mit etwas Vorbereitung aber genug Features, um meine aktuellen Probleme zu lösen:
bool UnitConverter::measuresEnergy(const Unit &unit) const { string measureOfUnit("1 " + lexical_cast<string> (unit)); unit_t measure; ul_parse(measureOfUnit.c_str(), &measure); unit_t reference; ul_parse("1 Wh", &reference); return ul_cmp(&reference, &measure) & UL_SAME_UNIT; } bool UnitConverter::convertToKiloWattHours(Quantity &quantity) const { string unit(" " + lexical_cast<string> (quantity.getUnit())); if (!measuresEnergy(quantity.getUnit())) { throw IncompatibleMeasureException(); } if (unit != " kWh") { string textualQuantity(lexical_cast<string> (quantity.getValue()) + unit); unit_t measure; ul_parse(textualQuantity.c_str(), &measure); quantity.setValue(measure.factor / 1000 / 3600); quantity.setUnit(Unit("kWh")); return true; } return false; } void UnitConverter::enableUnitArithmetic() { if (!ul_init()) { throw PhysicsSubsystemException(); } ul_parse_rule("N= 1 kg * m / s^2"); ul_parse_rule("Nm= 1 N * m"); ul_parse_rule("J= 1 Nm"); ul_parse_rule("W= 1 J/s"); ul_parse_rule("min= 60 s"); ul_parse_rule("h= 60 min"); ul_parse_rule("Wh= 1 W * h"); ul_parse_rule("Ws= 1 W * s"); } void UnitConverter::disableUnitArithmetic() { ul_quit(); }Besten Dank also nochmals und Gruss
Kessi