[calculation] Dimension in additional output for values with units

This commit is contained in:
Laury
2022-06-18 22:35:09 +02:00
parent 125e1a8a82
commit e8ea693e5c
13 changed files with 300 additions and 16 deletions

View File

@@ -2,6 +2,7 @@
#define POINCARE_UNIT_H
#include <poincare/expression.h>
#include <apps/i18n.h>
namespace Poincare {
@@ -105,6 +106,7 @@ public:
{}
virtual const Vector<int> dimensionVector() const { return Vector<int>{.time = 0, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; };
virtual const I18n::Message dimensionMessage() const = 0;
virtual int numberOfRepresentatives() const { return 0; };
/* representativesOfSameDimension returns a pointer to the array containing
* all representatives for this's dimension. */
@@ -146,6 +148,7 @@ public:
public:
constexpr static TimeRepresentative Default() { return TimeRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 1, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::TimeDimension; }
int numberOfRepresentatives() const override { return 7; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -160,6 +163,7 @@ public:
public:
constexpr static DistanceRepresentative Default() { return DistanceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 1, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::DistanceDimension; }
int numberOfRepresentatives() const override { return 8; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -175,6 +179,7 @@ public:
public:
constexpr static MassRepresentative Default() { return MassRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 0, .mass = 1, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::MassDimension; }
int numberOfRepresentatives() const override { return 7; }
const Representative * representativesOfSameDimension() const override;
const Prefix * basePrefix() const override;
@@ -191,6 +196,7 @@ public:
public:
constexpr static CurrentRepresentative Default() { return CurrentRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 0, .mass = 0, .current = 1, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::CurrentDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -204,6 +210,7 @@ public:
static double ConvertTemperatures(double value, const Representative * source, const Representative * target);
constexpr static TemperatureRepresentative Default() { return TemperatureRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 0, .mass = 0, .current = 0, .temperature = 1, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::TemperatureDimension; }
int numberOfRepresentatives() const override { return 3; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -221,6 +228,7 @@ public:
public:
constexpr static AmountOfSubstanceRepresentative Default() { return AmountOfSubstanceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 1, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::AmountOfSubstanceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -233,6 +241,7 @@ public:
public:
constexpr static LuminousIntensityRepresentative Default() { return LuminousIntensityRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 1}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::LuminousIntensityDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
bool isBaseUnit() const override { return this == representativesOfSameDimension(); }
@@ -245,6 +254,7 @@ public:
public:
constexpr static FrequencyRepresentative Default() { return FrequencyRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -1, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::FrequencyDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -256,6 +266,7 @@ public:
public:
constexpr static ForceRepresentative Default() { return ForceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = 1, .mass = 1, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ForceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -267,6 +278,7 @@ public:
public:
constexpr static PressureRepresentative Default() { return PressureRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = -1, .mass = 1, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::PressureDimension; }
int numberOfRepresentatives() const override { return 3; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -278,6 +290,7 @@ public:
public:
constexpr static EnergyRepresentative Default() { return EnergyRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = 2, .mass = 1, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::EnergyDimension; }
int numberOfRepresentatives() const override { return 2; }
const Representative * representativesOfSameDimension() const override;
bool hasSpecialAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return true; }
@@ -291,6 +304,7 @@ public:
public:
constexpr static PowerRepresentative Default() { return PowerRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -3, .distance = 2, .mass = 1, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::PowerDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -303,6 +317,7 @@ public:
using Representative::Representative;
constexpr static ElectricChargeRepresentative Default() { return ElectricChargeRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 1, .distance = 0, .mass = 0, .current = 1, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ElectricChargeDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
};
@@ -312,6 +327,7 @@ public:
public:
constexpr static ElectricPotentialRepresentative Default() { return ElectricPotentialRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -3, .distance = 2, .mass = 1, .current = -1, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ElectricPotentialDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -323,6 +339,7 @@ public:
public:
constexpr static ElectricCapacitanceRepresentative Default() { return ElectricCapacitanceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 4, .distance = -2, .mass = -1, .current = 2, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ElectricCapacitanceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -334,6 +351,7 @@ public:
public:
constexpr static ElectricResistanceRepresentative Default() { return ElectricResistanceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -3, .distance = 2, .mass = 1, .current = -2, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ElectricResistanceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -345,6 +363,7 @@ public:
public:
constexpr static ElectricConductanceRepresentative Default() { return ElectricConductanceRepresentative(nullptr, 1., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 3, .distance = -2, .mass = -1, .current = 2, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::ElectricConductanceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -356,6 +375,7 @@ public:
public:
constexpr static MagneticFluxRepresentative Default() { return MagneticFluxRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = 2, .mass = 1, .current = -1, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::MagneticFluxDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -367,6 +387,7 @@ public:
public:
constexpr static MagneticFieldRepresentative Default() { return MagneticFieldRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = 0, .mass = 1, .current = -1, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::MagneticFieldDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -378,6 +399,7 @@ public:
public:
constexpr static InductanceRepresentative Default() { return InductanceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -2, .distance = 2, .mass = 1, .current = -2, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::InductanceDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -389,6 +411,7 @@ public:
public:
constexpr static CatalyticActivityRepresentative Default() { return CatalyticActivityRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = -1, .distance = 0, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 1, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::CatalyticActivityDimension; }
int numberOfRepresentatives() const override { return 1; }
const Representative * representativesOfSameDimension() const override;
private:
@@ -400,6 +423,7 @@ public:
public:
constexpr static SurfaceRepresentative Default() { return SurfaceRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 2, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::SurfaceDimension; }
int numberOfRepresentatives() const override { return 2; }
const Representative * representativesOfSameDimension() const override;
const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const override;
@@ -414,6 +438,7 @@ public:
public:
constexpr static VolumeRepresentative Default() { return VolumeRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int> dimensionVector() const override { return Vector<int>{.time = 0, .distance = 3, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::VolumeDimension; }
int numberOfRepresentatives() const override { return 8; }
const Representative * representativesOfSameDimension() const override;
const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const override;
@@ -428,6 +453,7 @@ public:
public:
constexpr static SpeedRepresentative Default() { return SpeedRepresentative(nullptr, 0., Prefixable::None, Prefixable::None); }
const Vector<int>dimensionVector() const override { return Vector<int>{.time = -1, .distance = 1, .mass = 0, .current = 0, .temperature = 0, .amountOfSubstance = 0, .luminousIntensity = 0}; }
const I18n::Message dimensionMessage() const override { return I18n::Message::SpeedDimension; }
const Representative * standardRepresentative(double value, double exponent, ExpressionNode::ReductionContext reductionContext, const Prefix * * prefix) const override { return nullptr; }
bool hasSpecialAdditionalExpressions(double value, Preferences::UnitFormat unitFormat) const override { return true; }
int setAdditionalExpressions(double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) const override;
@@ -680,7 +706,7 @@ public:
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, Preferences::UnitFormat unitFormat);
static int SetAdditionalExpressions(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext);
static int SetAdditionalExpressionsAndMessage(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext, I18n::Message * message);
static Expression BuildSplit(double value, const Unit * units, int length, ExpressionNode::ReductionContext reductionContext);
static Expression ConvertTemperatureUnits(Expression e, Unit unit, ExpressionNode::ReductionContext reductionContext);

View File

@@ -10,6 +10,7 @@
#include <assert.h>
#include <limits.h>
#include <utility>
#include <apps/i18n.h>
namespace Poincare {
@@ -775,11 +776,10 @@ bool Unit::ShouldDisplayAdditionalOutputs(double value, Expression unit, Prefere
return e.type() == ExpressionNode::Type::Unit && !e.convert<Unit>().isBaseUnit();
};
return (representative != nullptr && representative->hasSpecialAdditionalExpressions(value, unitFormat))
|| unit.hasExpression(isNonBase, nullptr);
return representative != nullptr || unit.hasExpression(isNonBase, nullptr);
}
int Unit::SetAdditionalExpressions(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext) {
int Unit::SetAdditionalExpressionsAndMessage(Expression units, double value, Expression * dest, int availableLength, ExpressionNode::ReductionContext reductionContext, I18n::Message * message) {
if (units.isUninitialized()) {
return 0;
}
@@ -787,6 +787,7 @@ int Unit::SetAdditionalExpressions(Expression units, double value, Expression *
if (!representative) {
return 0;
}
*message = representative->dimensionMessage();
return representative->setAdditionalExpressions(value, dest, availableLength, reductionContext);
}

View File

@@ -456,7 +456,8 @@ void assert_additional_results_compute_to(const char * expression, const char *
quiz_assert(length == 0);
return;
}
const int numberOfResults = Unit::SetAdditionalExpressions(units, value, additional, maxNumberOfResults, reductionContext);
I18n::Message unitMessage;
const int numberOfResults = Unit::SetAdditionalExpressionsAndMessage(units, value, additional, maxNumberOfResults, reductionContext, unitMessage);
quiz_assert(numberOfResults == length);
for (int i = 0; i < length; i++) {