mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare/unit] Remove some additional results
Imperial additional results now only appear when the selected unit system is Imperial. Change-Id: Icc314d0148810bea67e4d729179393f1fceaf214
This commit is contained in:
committed by
Émilie Feral
parent
801c61549c
commit
860ce558c2
@@ -257,10 +257,10 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
|
||||
/* FIXME : When this method is accessed via leaving the additional outputs,
|
||||
* ie via a press on BACK, the reduction is interrupted, and removeUnit
|
||||
* goes badly.*/
|
||||
PoincareHelpers::Reduce(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined);
|
||||
PoincareHelpers::Reduce(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User, ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None);
|
||||
o = o.removeUnit(&unit);
|
||||
double value = PoincareHelpers::ApproximateToScalar<double>(o, App::app()->localContext());
|
||||
return (Unit::ShouldDisplayAdditionalOutputs(value, unit)) ? AdditionalInformationType::Unit : AdditionalInformationType::None;
|
||||
return (Unit::ShouldDisplayAdditionalOutputs(value, unit, GlobalPreferences::sharedGlobalPreferences()->unitFormat())) ? AdditionalInformationType::Unit : AdditionalInformationType::None;
|
||||
}
|
||||
if (o.isBasedIntegerCappedBy(k_maximalIntegerWithAdditionalInformation)) {
|
||||
return AdditionalInformationType::Integer;
|
||||
|
||||
@@ -110,7 +110,7 @@ public:
|
||||
virtual const Prefix * basePrefix() const { return Prefix::EmptyPrefix(); }
|
||||
virtual bool isBaseUnit() const { return false; }
|
||||
virtual const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const { return DefaultFindBestRepresentative(value, exponent, representativesOfSameDimension(), numberOfRepresentatives(), prefix); }
|
||||
virtual bool hasAdditionalExpressions(double value) const { return true; }
|
||||
virtual bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const { return true; }
|
||||
virtual int setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const { return 0; }
|
||||
const char * rootSymbol() const { return m_rootSymbol; }
|
||||
double ratio() const { return m_ratio; }
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
int numberOfRepresentatives() const override { return 7; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
bool hasAdditionalExpressions(double value) const override { return m_ratio * value >= representativesOfSameDimension()[1].ratio(); }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return m_ratio * value >= representativesOfSameDimension()[1].ratio(); }
|
||||
int setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const override;
|
||||
private:
|
||||
using Representative::Representative;
|
||||
@@ -157,6 +157,7 @@ public:
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const override;
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return unitFormat == Preferences::UnitFormat::Imperial; }
|
||||
int setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const override;
|
||||
private:
|
||||
using Representative::Representative;
|
||||
@@ -172,6 +173,7 @@ public:
|
||||
const Prefix * basePrefix() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const override;
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return unitFormat == Preferences::UnitFormat::Imperial; }
|
||||
int setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const override;
|
||||
private:
|
||||
using Representative::Representative;
|
||||
@@ -185,7 +187,7 @@ public:
|
||||
int numberOfRepresentatives() const override { return 1; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
bool hasAdditionalExpressions(double value) const override { return false; }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return false; }
|
||||
private:
|
||||
using Representative::Representative;
|
||||
};
|
||||
@@ -198,7 +200,7 @@ public:
|
||||
int numberOfRepresentatives() const override { return 1; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
bool hasAdditionalExpressions(double value) const override { return false; }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return false; }
|
||||
private:
|
||||
using Representative::Representative;
|
||||
};
|
||||
@@ -211,7 +213,7 @@ public:
|
||||
int numberOfRepresentatives() const override { return 1; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
bool hasAdditionalExpressions(double value) const override { return false; }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return false; }
|
||||
private:
|
||||
using Representative::Representative;
|
||||
};
|
||||
@@ -224,7 +226,7 @@ public:
|
||||
int numberOfRepresentatives() const override { return 1; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
|
||||
bool hasAdditionalExpressions(double value) const override { return false; }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return false; }
|
||||
private:
|
||||
using Representative::Representative;
|
||||
};
|
||||
@@ -236,7 +238,7 @@ public:
|
||||
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -1, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminuousIntensity = 0}; }
|
||||
int numberOfRepresentatives() const override { return 1; }
|
||||
const Representative * representativesOfSameDimension() const override;
|
||||
bool hasAdditionalExpressions(double value) const override { return false; }
|
||||
bool hasAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return false; }
|
||||
private:
|
||||
using Representative::Representative;
|
||||
};
|
||||
@@ -652,7 +654,7 @@ public:
|
||||
static Unit Builder(const Representative * representative, const Prefix * prefix);
|
||||
static bool CanParse(const char * symbol, size_t length, const Representative * * representative, const Prefix * * prefix);
|
||||
static void ChooseBestRepresentativeAndPrefixForValue(Expression units, double * value, ExpressionNode::ReductionContext reductionContext);
|
||||
static bool ShouldDisplayAdditionalOutputs(double value, Expression unit);
|
||||
static bool ShouldDisplayAdditionalOutputs(double value, Expression unit, Preferences::UnitFormat unitFormat);
|
||||
static int SetAdditionalExpressions(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext);
|
||||
static Expression BuildSplit(double value, const Unit * units, int length, ExpressionNode::ReductionContext reductionContext);
|
||||
|
||||
|
||||
@@ -437,6 +437,9 @@ const UnitNode::Representative * UnitNode::DistanceRepresentative::standardRepre
|
||||
|
||||
int UnitNode::DistanceRepresentative::setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const {
|
||||
assert(availableLength >= 1);
|
||||
if (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) {
|
||||
return 0;
|
||||
}
|
||||
const Unit splitUnits[] = {
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_inchRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_footRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
@@ -461,6 +464,9 @@ const UnitNode::Representative * UnitNode::MassRepresentative::standardRepresent
|
||||
|
||||
int UnitNode::MassRepresentative::setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const {
|
||||
assert(availableLength >= 1);
|
||||
if (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) {
|
||||
return 0;
|
||||
}
|
||||
const Unit splitUnits[] = {
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_ounceRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_poundRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
@@ -501,13 +507,21 @@ const UnitNode::Representative * UnitNode::SurfaceRepresentative::standardRepres
|
||||
|
||||
int UnitNode::SurfaceRepresentative::setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const {
|
||||
assert(availableLength >= 2);
|
||||
int k = (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) ? 0 : 1;
|
||||
Expression * destMetric = dest + k;
|
||||
Expression * destImperial = dest + (1 - k);
|
||||
Expression * destMetric;
|
||||
Expression * destImperial = nullptr;
|
||||
if (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) {
|
||||
destMetric = dest;
|
||||
} else {
|
||||
destImperial = dest;
|
||||
destMetric = dest + 1;
|
||||
}
|
||||
// 1. Convert to hectares
|
||||
const Representative * hectare = representativesOfSameDimension() + Unit::k_hectareRepresentativeIndex;
|
||||
*destMetric = Multiplication::Builder(Float<double>::Builder(value / hectare->ratio()), Unit::Builder(hectare, Prefix::EmptyPrefix()));
|
||||
// 2. Convert to acres
|
||||
if (!destImperial) {
|
||||
return 1;
|
||||
}
|
||||
const Representative * acre = representativesOfSameDimension() + Unit::k_acreRepresentativeIndex;
|
||||
*destImperial = Multiplication::Builder(Float<double>::Builder(value / acre->ratio()), Unit::Builder(acre, Prefix::EmptyPrefix()));
|
||||
return 2;
|
||||
@@ -523,9 +537,14 @@ const UnitNode::Representative * UnitNode::VolumeRepresentative::standardReprese
|
||||
|
||||
int UnitNode::VolumeRepresentative::setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const {
|
||||
assert(availableLength >= 2);
|
||||
int k = (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) ? 0 : 1;
|
||||
Expression * destMetric = dest + k;
|
||||
Expression * destImperial = dest + (1 - k);
|
||||
Expression * destMetric;
|
||||
Expression * destImperial = nullptr;
|
||||
if (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) {
|
||||
destMetric = dest;
|
||||
} else {
|
||||
destImperial = dest;
|
||||
destMetric = dest + 1;
|
||||
}
|
||||
// 1. Convert to liters
|
||||
const Representative * liter = representativesOfSameDimension() + Unit::k_literRepresentativeIndex;
|
||||
double adjustedValue = value / liter->ratio();
|
||||
@@ -534,6 +553,9 @@ int UnitNode::VolumeRepresentative::setAdditionalExpressions(double value, Expre
|
||||
Float<double>::Builder(adjustedValue * pow(10., -literPrefix->exponent())),
|
||||
Unit::Builder(liter, literPrefix));
|
||||
// 2. Convert to imperial volumes
|
||||
if (!destImperial) {
|
||||
return 1;
|
||||
}
|
||||
const Unit splitUnits[] = {
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_cupRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
Unit::Builder(representativesOfSameDimension() + Unit::k_pintRepresentativeIndex, Prefix::EmptyPrefix()),
|
||||
@@ -546,9 +568,14 @@ int UnitNode::VolumeRepresentative::setAdditionalExpressions(double value, Expre
|
||||
|
||||
int UnitNode::SpeedRepresentative::setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const {
|
||||
assert(availableLength >= 2);
|
||||
int k = (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) ? 0 : 1;
|
||||
Expression * destMetric = dest + k;
|
||||
Expression * destImperial = dest + (1 - k);
|
||||
Expression * destMetric;
|
||||
Expression * destImperial = nullptr;
|
||||
if (reductionContext.unitFormat() == Preferences::UnitFormat::Metric) {
|
||||
destMetric = dest;
|
||||
} else {
|
||||
destImperial = dest;
|
||||
destMetric = dest + 1;
|
||||
}
|
||||
// 1. Convert to km/h
|
||||
const Representative * meter = DistanceRepresentative::Default().representativesOfSameDimension() + Unit::k_meterRepresentativeIndex;
|
||||
const Representative * hour = TimeRepresentative::Default().representativesOfSameDimension() + Unit::k_hourRepresentativeIndex;
|
||||
@@ -558,6 +585,9 @@ int UnitNode::SpeedRepresentative::setAdditionalExpressions(double value, Expres
|
||||
Unit::Builder(meter, Prefix::Prefixes() + Unit::k_kiloPrefixIndex),
|
||||
Power::Builder(Unit::Builder(hour, Prefix::EmptyPrefix()), Rational::Builder(-1))));
|
||||
// 2. Convert to mph
|
||||
if (!destImperial) {
|
||||
return 1;
|
||||
}
|
||||
const Representative * mile = DistanceRepresentative::Default().representativesOfSameDimension() + Unit::k_mileRepresentativeIndex;
|
||||
*destImperial = Multiplication::Builder(
|
||||
Float<double>::Builder(value / mile->ratio() * hour->ratio()),
|
||||
@@ -676,10 +706,12 @@ void Unit::ChooseBestRepresentativeAndPrefixForValue(Expression units, double *
|
||||
}
|
||||
}
|
||||
|
||||
bool Unit::ShouldDisplayAdditionalOutputs(double value, Expression unit) {
|
||||
bool Unit::ShouldDisplayAdditionalOutputs(double value, Expression unit, Preferences::UnitFormat unitFormat) {
|
||||
UnitNode::Vector<int> vector = UnitNode::Vector<int>::FromBaseUnits(unit);
|
||||
const Representative * representative = Representative::RepresentativeForDimension(vector);
|
||||
return representative != nullptr && representative->hasAdditionalExpressions(value);
|
||||
return representative != nullptr
|
||||
&& ((unit.type() == ExpressionNode::Type::Unit && !unit.convert<Unit>().isBaseUnit())
|
||||
|| representative->hasAdditionalExpressions(value, unitFormat));
|
||||
}
|
||||
|
||||
int Unit::SetAdditionalExpressions(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) {
|
||||
|
||||
@@ -394,18 +394,18 @@ QUIZ_CASE(poincare_properties_remove_unit) {
|
||||
assert_reduced_expression_unit_is("_L^2×3×_s", "_m^6×_s");
|
||||
}
|
||||
|
||||
void assert_additional_results_compute_to(const char * expression, const char * * results, int length) {
|
||||
void assert_additional_results_compute_to(const char * expression, const char * * results, int length, Preferences::UnitFormat unitFormat = Metric) {
|
||||
Shared::GlobalContext globalContext;
|
||||
constexpr int maxNumberOfResults = 5;
|
||||
assert(length <= maxNumberOfResults);
|
||||
Expression additional[maxNumberOfResults];
|
||||
ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(&globalContext, Cartesian, Degree, Metric, User, ReplaceAllSymbolsWithUndefined, DefaultUnitConversion);
|
||||
ExpressionNode::ReductionContext reductionContext = ExpressionNode::ReductionContext(&globalContext, Cartesian, Degree, unitFormat, User, ReplaceAllSymbolsWithUndefined, DefaultUnitConversion);
|
||||
Expression e = parse_expression(expression, &globalContext, false).reduce(reductionContext);
|
||||
Expression units;
|
||||
e = e.removeUnit(&units);
|
||||
double value = e.approximateToScalar<double>(&globalContext, Cartesian, Degree);
|
||||
|
||||
if (!Unit::ShouldDisplayAdditionalOutputs(value, units)) {
|
||||
if (!Unit::ShouldDisplayAdditionalOutputs(value, units, unitFormat)) {
|
||||
quiz_assert(length == 0);
|
||||
return;
|
||||
}
|
||||
@@ -429,27 +429,33 @@ QUIZ_CASE(poincare_expression_additional_results) {
|
||||
|
||||
// Distance
|
||||
const char * array4[1] = {"19×_mi+853×_yd+1×_ft+7×_in"};
|
||||
assert_additional_results_compute_to("1234567×_in", array4, 1);
|
||||
assert_additional_results_compute_to("1234567×_in", array4, 1, Imperial);
|
||||
const char * array5[1] = {"1×_yd+7.700787×_in"};
|
||||
assert_additional_results_compute_to("1.11×_m", array5, 1);
|
||||
assert_additional_results_compute_to("1.11×_m", array5, 1, Imperial);
|
||||
assert_additional_results_compute_to("1.11×_m", nullptr, 0, Metric);
|
||||
|
||||
// Masses
|
||||
const char * array6[1] = {"1×_shtn+240×_lb"};
|
||||
assert_additional_results_compute_to("1×_lgtn", array6, 1);
|
||||
assert_additional_results_compute_to("1×_lgtn", array6, 1, Imperial);
|
||||
const char * array7[1] = {"2×_lb+3.273962×_oz"};
|
||||
assert_additional_results_compute_to("1×_kg", array7, 1);
|
||||
assert_additional_results_compute_to("1×_kg", array7, 1, Imperial);
|
||||
assert_additional_results_compute_to("1×_kg", nullptr, 0, Metric);
|
||||
|
||||
// Energy
|
||||
const char * array8[2] = {"1×_kW×_h", "2.246943ᴇ13×_TeV"};
|
||||
assert_additional_results_compute_to("3.6×_MN_m", array8, 2);
|
||||
|
||||
// Volume
|
||||
const char * array9[2] = {"1000×_L", "264×_gal+1×_pt+0.7528377×_cup"};
|
||||
assert_additional_results_compute_to("1×_m^3", array9, 2);
|
||||
const char * array10[2] = {"182.5426×_L", "48×_gal+1×_pt+1.5625×_cup"};
|
||||
assert_additional_results_compute_to("12345×_tbsp", array10, 2);
|
||||
const char * array9[2] = {"264×_gal+1×_pt+0.7528377×_cup", "1000×_L"};
|
||||
assert_additional_results_compute_to("1×_m^3", array9, 2, Imperial);
|
||||
const char * array10[2] = {"48×_gal+1×_pt+1.5625×_cup", "182.5426×_L"};
|
||||
assert_additional_results_compute_to("12345×_tbsp", array10, 2, Imperial);
|
||||
const char * array11[2] = {"182.5426×_L"};
|
||||
assert_additional_results_compute_to("12345×_tbsp", array11, 1, Metric);
|
||||
|
||||
// Speed
|
||||
const char * array11[2] = {"3.6×_km×_h^\x12-1\x13", "2.236936×_mi×_h^\x12-1\x13"};
|
||||
assert_additional_results_compute_to("1×_m/_s", array11, 2);
|
||||
const char * array12[1] = {"3.6×_km×_h^\x12-1\x13"};
|
||||
assert_additional_results_compute_to("1×_m/_s", array12, 1, Metric);
|
||||
const char * array13[2] = {"2.236936×_mi×_h^\x12-1\x13", "3.6×_km×_h^\x12-1\x13"};
|
||||
assert_additional_results_compute_to("1×_m/_s", array13, 2, Imperial);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user