mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Multiplication::shallowBeautify: Keep the unit when the value
is 0 or undefined, add tests
This commit is contained in:
@@ -510,36 +510,44 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
|
||||
result = units;
|
||||
} else {
|
||||
double value = result.approximateToScalar<double>(reductionContext.context(), reductionContext.complexFormat(), reductionContext.angleUnit());
|
||||
if (std::isinf(value)) {
|
||||
result = Infinity::Builder(false); //FIXME sign?
|
||||
} else if (std::isnan(value)) {
|
||||
if (std::isnan(value)) {
|
||||
// If the value is undefined, return "undef" without any unit
|
||||
result = Undefined::Builder();
|
||||
} else {
|
||||
// Identify the first Unit factor and its exponent
|
||||
Expression firstFactor = units;
|
||||
int exponent = 1;
|
||||
if (firstFactor.type() == ExpressionNode::Type::Multiplication) {
|
||||
firstFactor = firstFactor.childAtIndex(0);
|
||||
}
|
||||
if (firstFactor.type() == ExpressionNode::Type::Power) {
|
||||
Expression exp = firstFactor.childAtIndex(1);
|
||||
firstFactor = firstFactor.childAtIndex(0);
|
||||
assert(exp.type() == ExpressionNode::Type::Rational && static_cast<Rational &>(exp).isInteger());
|
||||
Integer expInt = static_cast<Rational &>(exp).signedIntegerNumerator();
|
||||
if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) {
|
||||
exponent = expInt.extractedInt();
|
||||
} else {
|
||||
// The exponent is too large to be extracted, so do not try to use it.
|
||||
exponent = 0;
|
||||
Expression resultWithoutUnit;
|
||||
if (std::isinf(value)) {
|
||||
resultWithoutUnit = Infinity::Builder(value < 0.0);
|
||||
} else {
|
||||
// Find the right unit prefix when the value ≠ 0
|
||||
if (value != 0.0) {
|
||||
// Identify the first Unit factor and its exponent
|
||||
Expression firstFactor = units;
|
||||
int exponent = 1;
|
||||
if (firstFactor.type() == ExpressionNode::Type::Multiplication) {
|
||||
firstFactor = firstFactor.childAtIndex(0);
|
||||
}
|
||||
if (firstFactor.type() == ExpressionNode::Type::Power) {
|
||||
Expression exp = firstFactor.childAtIndex(1);
|
||||
firstFactor = firstFactor.childAtIndex(0);
|
||||
assert(exp.type() == ExpressionNode::Type::Rational && static_cast<Rational &>(exp).isInteger());
|
||||
Integer expInt = static_cast<Rational &>(exp).signedIntegerNumerator();
|
||||
if (expInt.isLowerThan(Integer(Integer::k_maxExtractableInteger))) {
|
||||
exponent = expInt.extractedInt();
|
||||
} else {
|
||||
// The exponent is too large to be extracted, so do not try to use it.
|
||||
exponent = 0;
|
||||
}
|
||||
}
|
||||
assert(firstFactor.type() == ExpressionNode::Type::Unit);
|
||||
// Choose its multiple and update value accordingly
|
||||
if (exponent != 0) {
|
||||
static_cast<Unit&>(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(firstFactor.type() == ExpressionNode::Type::Unit);
|
||||
// Choose its multiple and update value accordingly
|
||||
if (exponent != 0) {
|
||||
static_cast<Unit&>(firstFactor).chooseBestMultipleForValue(value, exponent, reductionContext);
|
||||
resultWithoutUnit = Float<double>::Builder(value);
|
||||
}
|
||||
// Build final Expression
|
||||
result = Multiplication::Builder(Float<double>::Builder(value), units);
|
||||
result = Multiplication::Builder(resultWithoutUnit, units);
|
||||
static_cast<Multiplication &>(result).mergeMultiplicationChildrenInPlace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,6 +309,16 @@ QUIZ_CASE(poincare_simplification_units) {
|
||||
assert_parsed_expression_simplify_to("_A^2×_s^4×_kg^(-1)×_m^(-3)", "_F×_m^\u0012-1\u0013"); // Vacuum magnetic permeability 𝝴0
|
||||
assert_parsed_expression_simplify_to("_kg×_s^(-3)×_K^(-4)", "_K^\u0012-4\u0013×_kg×_s^\u0012-3\u0013"); // Stefan–Boltzmann constant _W×_m^-2×_K^-4
|
||||
|
||||
/* Keep units for 0, infinity float results, Remove unit for undefined
|
||||
* expression */
|
||||
//assert_parsed_expression_simplify_to("0_s", "0_s");
|
||||
assert_parsed_expression_simplify_to("inf×_s", "inf×_s");
|
||||
//assert_parsed_expression_simplify_to("-inf×_s", "-inf×_s");
|
||||
//assert_parsed_expression_simplify_to("2_s+3_s-5_s", "0_s");
|
||||
assert_parsed_expression_simplify_to("normcdf(0,20,3)×_s", "0×_s");
|
||||
//assert_parsed_expression_simplify_to("log(0)×_s", "-inf×_s");
|
||||
assert_parsed_expression_simplify_to("log(undef)*_s", "undef");
|
||||
|
||||
/* Units with invalid exponent */
|
||||
assert_parsed_expression_simplify_to("_s^(1/2)", "undef");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user