Merge pull request #338 from coco33920/correct_units

[Change] A way to stop the US Unit's imperialism
This commit is contained in:
Quentin
2020-06-12 22:32:53 +02:00
committed by GitHub
2 changed files with 28 additions and 53 deletions

View File

@@ -255,7 +255,7 @@ public:
Representative("pc", "180*60*60/π*_au",
Representative::Prefixable::No,
NoPrefix),
Representative("ft", "0.3048*_m", // used meters to allow for conversion
Representative("ft", nullptr, // used meters to allow for conversion
Representative::Prefixable::No,
NoPrefix),
Representative("in", "(1/12)*_ft",
@@ -281,7 +281,7 @@ public:
Representative("Da", "(6.02214076*10^23*1000)^-1*_kg",
Representative::Prefixable::Yes,
NoPrefix),
Representative("lb", "453.59237*_g",
Representative("lb", nullptr,
Representative::Prefixable::Yes,
NoPrefix),
Representative("oz", "(1/16)*_lb",

View File

@@ -24,8 +24,7 @@
namespace Poincare {
const int numberOfFondamentalUnits = 10;
/* Multiplication Node */
ExpressionNode::Sign MultiplicationNode::sign(Context * context) const {
@@ -323,15 +322,15 @@ Expression Multiplication::shallowReduce(ExpressionNode::ReductionContext reduct
return privateShallowReduce(reductionContext, true, true);
}
static void ExponentsCopy(Integer (&dst)[8], const Integer (&src)[8]) {
for (int i = 0; i < 8; i++) {
static void ExponentsCopy(Integer (&dst)[numberOfFondamentalUnits], const Integer (&src)[numberOfFondamentalUnits]) {
for (int i = 0; i < numberOfFondamentalUnits; i++) {
dst[i] = src[i];
}
}
static void ExponentsMetrics(const Integer (&exponents)[8], size_t & supportSize, Integer & norm) {
static void ExponentsMetrics(const Integer (&exponents)[numberOfFondamentalUnits], size_t & supportSize, Integer & norm) {
assert(supportSize == 0 && norm.isZero());
for (int i = 0; i < 8; i++) {
for (int i = 0; i < numberOfFondamentalUnits; i++) {
Integer unsignedExponent = exponents[i];
unsignedExponent.setNegative(false);
if (!unsignedExponent.isZero()) {
@@ -341,7 +340,7 @@ static void ExponentsMetrics(const Integer (&exponents)[8], size_t & supportSize
}
}
static void ExponentsOfBaseUnits(const Expression units, Integer (&exponents)[8]) {
static void ExponentsOfBaseUnits(const Expression units, Integer (&exponents)[numberOfFondamentalUnits]) {
// Make sure the provided Expression is a Multiplication
Expression u = units;
if (u.type() == ExpressionNode::Type::Unit || u.type() == ExpressionNode::Type::Power) {
@@ -367,30 +366,24 @@ static void ExponentsOfBaseUnits(const Expression units, Integer (&exponents)[8]
// Fill the exponents array with the unit's exponent
const int indexInTable = static_cast<Unit &>(factor).dimension() - Unit::DimensionTable;
assert(0 <= indexInTable && indexInTable < 8);
assert(0 <= indexInTable && indexInTable < numberOfFondamentalUnits);
exponents[indexInTable] = exponent;
}
}
static bool CanSimplifyUnitProduct(
const Integer (&unitsExponents)[8], const Integer (&entryUnitExponents)[8], const Integer entryUnitNorm, const Expression entryUnit,
const Integer (&unitsExponents)[numberOfFondamentalUnits], const Integer (&entryUnitExponents)[numberOfFondamentalUnits], const Integer entryUnitNorm, const Expression entryUnit,
Integer (*operationOnExponents)(const Integer & unitsExponent, const Integer & entryUnitExponent),
Expression & bestUnit, Integer & bestUnitNorm, Integer (&bestRemainderExponents)[8], size_t & bestRemainderSupportSize, Integer & bestRemainderNorm) {
Expression & bestUnit, Integer & bestUnitNorm, Integer (&bestRemainderExponents)[numberOfFondamentalUnits], size_t & bestRemainderSupportSize, Integer & bestRemainderNorm) {
/* This function tries to simplify a Unit product (given as the
* 'unitsExponents' Integer array), by applying a given operation. If the
* result of the operation is simpler, 'bestUnit' and
* 'bestRemainder' are updated accordingly. */
Integer simplifiedExponents[8] = {
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
};
for (int i = 0; i < 8; i++) {
Integer simplifiedExponents[numberOfFondamentalUnits];
for(int i = 0; i < numberOfFondamentalUnits; i++){
simplifiedExponents[i] = Integer(0);
}
for (int i = 0; i < numberOfFondamentalUnits; i++) {
simplifiedExponents[i] = operationOnExponents(unitsExponents[i], entryUnitExponents[i]);
}
size_t simplifiedSupportSize = 0;
@@ -440,30 +433,18 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
* - Repeat those steps until no more simplification is possible.
*/
Multiplication unitsAccu = Multiplication::Builder();
Integer unitsExponents[8] = {
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
};
Integer unitsExponents[numberOfFondamentalUnits];
for(int i = 0; i < numberOfFondamentalUnits; i++){
unitsExponents[i] = Integer(0);
}
ExponentsOfBaseUnits(units, unitsExponents);
size_t unitsSupportSize = 0;
Integer unitsNorm(0);
ExponentsMetrics(unitsExponents, unitsSupportSize, unitsNorm);
Integer bestRemainderExponents[8] = {
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
};
Integer bestRemainderExponents[numberOfFondamentalUnits];
for(int i = 0; i < numberOfFondamentalUnits; i++){
bestRemainderExponents[i] = Integer(0);
}
while (unitsSupportSize > 1) {
Expression bestUnit;
Integer bestUnitNorm(0);
@@ -471,16 +452,10 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu
Integer bestRemainderNorm = unitsNorm;
for (const Unit::Dimension * dim = Unit::DimensionTable + 8; dim < Unit::DimensionTableUpperBound; dim++) {
Unit entryUnit = Unit::Builder(dim, dim->stdRepresentative(), dim->stdRepresentativePrefix());
Integer entryUnitExponents[8] = {
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
Integer(0),
};
Integer entryUnitExponents[numberOfFondamentalUnits];
for(int i = 0; i < numberOfFondamentalUnits; i++){
entryUnitExponents[i] = Integer(0);
}
Integer entryUnitNorm(0);
size_t entryUnitSupportSize = 0;
ExponentsOfBaseUnits(entryUnit.clone().shallowReduce(reductionContext), entryUnitExponents);