mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Add Liter representation to classic unit conversion
This commit is contained in:
@@ -118,6 +118,7 @@ public:
|
||||
static int NumberOfBase10DigitsWithoutSign(const Integer & i);
|
||||
bool isOne() const { return (numberOfDigits() == 1 && digit(0) == 1 && !m_negative); };
|
||||
bool isTwo() const { return (numberOfDigits() == 1 && digit(0) == 2 && !m_negative); };
|
||||
bool isThree() const { return (numberOfDigits() == 1 && digit(0) == 3 && !m_negative); };
|
||||
bool isTen() const { return (numberOfDigits() == 1 && digit(0) == 10 && !m_negative); };
|
||||
bool isMinusOne() const { return (numberOfDigits() == 1 && digit(0) == 1 && m_negative); };
|
||||
bool isZero() const { return (numberOfDigits() == 0); };
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
// Basic test
|
||||
bool isZero() const { return unsignedNumerator().isZero(); }
|
||||
bool isOne() const { return signedNumerator().isOne() && isInteger(); }
|
||||
bool isThree() const { return signedNumerator().isThree() && isInteger(); }
|
||||
bool isMinusOne() const { return signedNumerator().isMinusOne() && isInteger(); }
|
||||
bool isHalf() const { return signedNumerator().isOne() && denominator().isTwo(); }
|
||||
bool isMinusHalf() const { return signedNumerator().isMinusOne() && denominator().isTwo(); }
|
||||
@@ -89,6 +90,7 @@ public:
|
||||
bool isNegative() const { return node()->isNegative(); }
|
||||
bool isZero() const { return node()->isZero(); }
|
||||
bool isOne() const { return node()->isOne(); }
|
||||
bool isThree() const { return node()->isThree(); }
|
||||
bool isMinusOne() const { return node()->isMinusOne(); }
|
||||
bool isHalf() const { return node()->isHalf(); }
|
||||
bool isMinusHalf() const { return node()->isMinusHalf(); }
|
||||
|
||||
@@ -414,9 +414,11 @@ public:
|
||||
Representative::Prefixable::Yes,
|
||||
NegativePrefixes),
|
||||
};
|
||||
// TODO: find a better way to find defines these pointers
|
||||
static const Representative constexpr * SecondRepresentative = &TimeRepresentatives[0];
|
||||
static const Representative constexpr * HourRepresentative = &TimeRepresentatives[2];
|
||||
static const Representative constexpr * MeterRepresentative = &DistanceRepresentatives[0];
|
||||
static const Representative constexpr * LiterRepresentative = &VolumeRepresentatives[0];
|
||||
static constexpr const Dimension DimensionTable[] = {
|
||||
/* The current table is sorted from most to least simple units.
|
||||
* The order determines the behavior of simplification.
|
||||
@@ -721,8 +723,10 @@ public:
|
||||
&EmptyPrefix
|
||||
),
|
||||
};
|
||||
// TODO: find a better way to find defines these pointers
|
||||
static const Dimension constexpr * TimeDimension = &DimensionTable[0] ;
|
||||
static const Dimension constexpr * DistanceDimension = &DimensionTable[1];
|
||||
static const Dimension constexpr * VolumeDimension = &DimensionTable[sizeof(DimensionTable)/sizeof(Dimension)-1];
|
||||
|
||||
static constexpr const Unit::Dimension * DimensionTableUpperBound =
|
||||
DimensionTable + sizeof(DimensionTable)/sizeof(Dimension);
|
||||
@@ -733,8 +737,10 @@ public:
|
||||
static Unit Builder(const Dimension * dimension, const Representative * representative, const Prefix * prefix);
|
||||
static Unit Kilometer() { return Builder(DistanceDimension, MeterRepresentative, &KiloPrefix); }
|
||||
static Unit Hour() { return Builder(TimeDimension, HourRepresentative, &EmptyPrefix); }
|
||||
static Unit Liter() { return Builder(VolumeDimension, LiterRepresentative, &EmptyPrefix); }
|
||||
|
||||
static bool IsISSpeed(Expression & e);
|
||||
static bool IsISVolume(Expression & e);
|
||||
bool isMeter() const;
|
||||
bool isSecond() const;
|
||||
|
||||
@@ -743,6 +749,7 @@ public:
|
||||
void chooseBestMultipleForValue(double & value, const int exponent, ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
static constexpr double MeterPerSecondToKilometerPerHourFactor = 60.0*60.0/1000.0;
|
||||
static constexpr double CubicMeterToLiterFactor = 10.0*10.0*10.0;
|
||||
private:
|
||||
UnitNode * node() const { return static_cast<UnitNode *>(Expression::node()); }
|
||||
Expression removeUnit(Expression * unit);
|
||||
|
||||
@@ -475,6 +475,11 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
)
|
||||
);
|
||||
}
|
||||
if (Unit::IsISVolume(units)) {
|
||||
value *= Unit::CubicMeterToLiterFactor;
|
||||
units = Unit::Liter();
|
||||
static_cast<Unit&>(units).chooseBestMultipleForValue(value, 1, reductionContext);
|
||||
}
|
||||
// TODO: what to do if no classic conversion?
|
||||
}
|
||||
if (result.isUninitialized()) {
|
||||
|
||||
@@ -370,6 +370,13 @@ bool Unit::IsISSpeed(Expression & e) {
|
||||
e.childAtIndex(1).childAtIndex(0).type() == ExpressionNode::Type::Unit && e.childAtIndex(1).childAtIndex(0).convert<Unit>().isSecond();
|
||||
}
|
||||
|
||||
bool Unit::IsISVolume(Expression & e) {
|
||||
// Form m^3
|
||||
return e.type() == ExpressionNode::Type::Power &&
|
||||
e.childAtIndex(0).type() == ExpressionNode::Type::Unit && e.childAtIndex(0).convert<Unit>().isMeter() &&
|
||||
e.childAtIndex(1).type() == ExpressionNode::Type::Rational && e.childAtIndex(1).convert<const Rational>().isThree();
|
||||
}
|
||||
|
||||
template Evaluation<float> UnitNode::templatedApproximate<float>(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
template Evaluation<double> UnitNode::templatedApproximate<double>(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
|
||||
@@ -1285,6 +1285,8 @@ QUIZ_CASE(poincare_simplification_unit_conversion) {
|
||||
assert_parsed_expression_simplify_to("1000000_cm", "1000000×_cm", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, NoUnitConversion);
|
||||
assert_parsed_expression_simplify_to("1000000_cm", "10000×_m", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, InternationalSystemUnitConversion);
|
||||
assert_parsed_expression_simplify_to("10_m/_h", "0.01×_km×_h^\x12-1\x13", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
assert_parsed_expression_simplify_to("0.2_m^3", "200×_L", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
assert_parsed_expression_simplify_to("0.000012_m^3", "1.2×_cL", User, Degree, Cartesian, ReplaceAllDefinedSymbolsWithDefinition, ClassicUnitConversion);
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_simplification_user_function) {
|
||||
|
||||
Reference in New Issue
Block a user