Skip to content

Commit

Permalink
Fix code errors listed at https://www.viva64.com/en/b/0616/ (issue #129
Browse files Browse the repository at this point in the history
…); Fix show repeating decimals in combination with show ending zeroes for rational numbers; Deprecate getBestUnit and convertToBestUnit, replaced with ...OptimalUnit, and replace getBest...Prefix with getOptimal...Prefix, in Calculator class
  • Loading branch information
hanna-kn committed Mar 14, 2019
1 parent 2df2de1 commit f367522
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 56 deletions.
6 changes: 3 additions & 3 deletions libqalculate/BuiltinFunctions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5782,10 +5782,10 @@ LiFunction::LiFunction() : MathFunction("Li", 2) {
setArgumentDefinition(2, arg);
}
bool LiFunction::representsReal(const MathStructure &vargs, bool) const {
return vargs.size() == 2 && vargs[0].representsInteger() && vargs[1].representsReal() && (vargs[1].representsNonPositive() || vargs[1].representsNonPositive() || ((vargs[1].isNumber() && vargs[1].number().isLessThanOrEqualTo(1)) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && ((KnownVariable*) vargs[1].variable())->get().number().isLessThanOrEqualTo(1)))) && ((vargs[0].representsPositive() || ((vargs[1].isNumber() && !vargs[1].number().isOne()) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && !((KnownVariable*) vargs[1].variable())->get().number().isOne()))));
return vargs.size() == 2 && vargs[0].representsInteger() && vargs[1].representsReal() && (vargs[1].representsNonPositive() || ((vargs[1].isNumber() && vargs[1].number().isLessThanOrEqualTo(1)) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && ((KnownVariable*) vargs[1].variable())->get().number().isLessThanOrEqualTo(1)))) && ((vargs[0].representsPositive() || ((vargs[1].isNumber() && !vargs[1].number().isOne()) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && !((KnownVariable*) vargs[1].variable())->get().number().isOne()))));
}
bool LiFunction::representsNonComplex(const MathStructure &vargs, bool) const {
return vargs.size() == 2 && vargs[0].representsInteger() && vargs[1].representsNonComplex() && (vargs[1].representsNonPositive() || vargs[1].representsNonPositive() || ((vargs[1].isNumber() && vargs[1].number().isLessThanOrEqualTo(1)) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && ((KnownVariable*) vargs[1].variable())->get().number().isLessThanOrEqualTo(1))));
return vargs.size() == 2 && vargs[0].representsInteger() && vargs[1].representsNonComplex() && (vargs[1].representsNonPositive() || ((vargs[1].isNumber() && vargs[1].number().isLessThanOrEqualTo(1)) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && ((KnownVariable*) vargs[1].variable())->get().number().isLessThanOrEqualTo(1))));
}
bool LiFunction::representsNumber(const MathStructure &vargs, bool) const {return vargs.size() == 2 && vargs[0].representsInteger() && (vargs[0].representsPositive() || (vargs[1].representsNumber() && ((vargs[1].isNumber() && !vargs[1].number().isOne()) || (vargs[1].isVariable() && vargs[1].variable()->isKnown() && ((KnownVariable*) vargs[1].variable())->get().isNumber() && !((KnownVariable*) vargs[1].variable())->get().number().isOne()))));}
int LiFunction::calculate(MathStructure &mstruct, const MathStructure &vargs, const EvaluationOptions &eo) {
Expand Down Expand Up @@ -6271,7 +6271,7 @@ int IntegrateFunction::calculate(MathStructure &mstruct, const MathStructure &va
MathStructure mtr2 = mstruct;
mtr2.replace(x_var, nr_begin);
mtr2.eval(eo2);
if(!mtr2.isNumber() || !mtr2.number().isReal() || !mtr.isNumber() || !mtr2.number().isReal()) b_unknown_precision = true;
if(!mtr2.isNumber() || !mtr2.number().isReal() || !mtr.isNumber() || !mtr.number().isReal()) b_unknown_precision = true;
if(!b_unknown_precision) {
Number ntr;
if(mtr2.number().isGreaterThan(mtr.number())) {
Expand Down
54 changes: 28 additions & 26 deletions libqalculate/Calculator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,15 @@ void autoConvert(const MathStructure &morig, MathStructure &mconv, const Evaluat
}
switch(eo.auto_post_conversion) {
case POST_CONVERSION_OPTIMAL: {
mconv.set(CALCULATOR->convertToBestUnit(morig, eo, false));
mconv.set(CALCULATOR->convertToOptimalUnit(morig, eo, false));
break;
}
case POST_CONVERSION_BASE: {
mconv.set(CALCULATOR->convertToBaseUnits(morig, eo));
break;
}
case POST_CONVERSION_OPTIMAL_SI: {
mconv.set(CALCULATOR->convertToBestUnit(morig, eo, true));
mconv.set(CALCULATOR->convertToOptimalUnit(morig, eo, true));
break;
}
default: {
Expand Down Expand Up @@ -857,7 +857,7 @@ DecimalPrefix *Calculator::getNearestDecimalPrefix(int exp10, int exp) const {
}
return decimal_prefixes[decimal_prefixes.size() - 1];
}
DecimalPrefix *Calculator::getBestDecimalPrefix(int exp10, int exp, bool all_prefixes) const {
DecimalPrefix *Calculator::getOptimalDecimalPrefix(int exp10, int exp, bool all_prefixes) const {
if(decimal_prefixes.size() <= 0 || exp10 == 0) return NULL;
int i = 0;
if(exp < 0) {
Expand Down Expand Up @@ -909,7 +909,7 @@ DecimalPrefix *Calculator::getBestDecimalPrefix(int exp10, int exp, bool all_pre
}
return p_prev;
}
DecimalPrefix *Calculator::getBestDecimalPrefix(const Number &exp10, const Number &exp, bool all_prefixes) const {
DecimalPrefix *Calculator::getOptimalDecimalPrefix(const Number &exp10, const Number &exp, bool all_prefixes) const {
if(decimal_prefixes.size() <= 0 || exp10.isZero()) return NULL;
int i = 0;
ComparisonResult c;
Expand Down Expand Up @@ -989,7 +989,7 @@ BinaryPrefix *Calculator::getNearestBinaryPrefix(int exp2, int exp) const {
}
return binary_prefixes[binary_prefixes.size() - 1];
}
BinaryPrefix *Calculator::getBestBinaryPrefix(int exp2, int exp) const {
BinaryPrefix *Calculator::getOptimalBinaryPrefix(int exp2, int exp) const {
if(binary_prefixes.size() <= 0 || exp2 == 0) return NULL;
int i = 0;
if(exp < 0) {
Expand Down Expand Up @@ -1039,7 +1039,7 @@ BinaryPrefix *Calculator::getBestBinaryPrefix(int exp2, int exp) const {
}
return p_prev;
}
BinaryPrefix *Calculator::getBestBinaryPrefix(const Number &exp2, const Number &exp) const {
BinaryPrefix *Calculator::getOptimalBinaryPrefix(const Number &exp2, const Number &exp) const {
if(binary_prefixes.size() <= 0 || exp2.isZero()) return NULL;
int i = 0;
ComparisonResult c;
Expand Down Expand Up @@ -2770,15 +2770,15 @@ MathStructure Calculator::calculate(string str, const EvaluationOptions &eo, Mat
current_stage = MESSAGE_STAGE_CONVERSION;
switch(eo.auto_post_conversion) {
case POST_CONVERSION_OPTIMAL: {
mstruct.set(convertToBestUnit(mstruct, eo, false));
mstruct.set(convertToOptimalUnit(mstruct, eo, false));
break;
}
case POST_CONVERSION_BASE: {
mstruct.set(convertToBaseUnits(mstruct, eo));
break;
}
case POST_CONVERSION_OPTIMAL_SI: {
mstruct.set(convertToBestUnit(mstruct, eo, true));
mstruct.set(convertToOptimalUnit(mstruct, eo, true));
break;
}
default: {}
Expand All @@ -2804,15 +2804,15 @@ MathStructure Calculator::calculate(const MathStructure &mstruct_to_calculate, c
} else {
switch(eo.auto_post_conversion) {
case POST_CONVERSION_OPTIMAL: {
mstruct.set(convertToBestUnit(mstruct, eo, false));
mstruct.set(convertToOptimalUnit(mstruct, eo, false));
break;
}
case POST_CONVERSION_BASE: {
mstruct.set(convertToBaseUnits(mstruct, eo));
break;
}
case POST_CONVERSION_OPTIMAL_SI: {
mstruct.set(convertToBestUnit(mstruct, eo, true));
mstruct.set(convertToOptimalUnit(mstruct, eo, true));
break;
}
default: {}
Expand Down Expand Up @@ -3279,7 +3279,8 @@ Unit *Calculator::findMatchingUnit(const MathStructure &mstruct) {
}
return NULL;
}
Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_local_currency) {
Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_local_currency) {return getOptimalUnit(u, allow_only_div, convert_to_local_currency);}
Unit *Calculator::getOptimalUnit(Unit *u, bool allow_only_div, bool convert_to_local_currency) {
switch(u->subtype()) {
case SUBTYPE_BASE_UNIT: {
if(convert_to_local_currency && u->isCurrency()) {
Expand All @@ -3300,7 +3301,7 @@ Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_loca
} else if(au->isSIUnit() && (au->firstBaseUnit()->subtype() == SUBTYPE_COMPOSITE_UNIT || au->firstBaseExponent() != 1)) {
return u;
} else {
return getBestUnit((Unit*) au->firstBaseUnit());
return getOptimalUnit((Unit*) au->firstBaseUnit());
}
}
case SUBTYPE_COMPOSITE_UNIT: {
Expand Down Expand Up @@ -3477,7 +3478,7 @@ Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_loca
if(points >= max_points && !minus) break;
}
if(!best_u) return u;
best_u = getBestUnit(best_u, false, convert_to_local_currency);
best_u = getOptimalUnit(best_u, false, convert_to_local_currency);
if(points > 1 && points < max_points - 1) {
CompositeUnit *cu_new = new CompositeUnit("", "temporary_composite_convert");
bool return_cu = minus;
Expand All @@ -3490,7 +3491,7 @@ Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_loca
if(minus) cu_mstruct *= best_u;
else cu_mstruct /= best_u;
cu_mstruct = convertToBaseUnits(cu_mstruct);
CompositeUnit *cu2 = new CompositeUnit("", "temporary_composite_convert_to_best_unit");
CompositeUnit *cu2 = new CompositeUnit("", "temporary_composite_convert_to_optimal_unit");
bool b = false;
for(size_t i = 1; i <= cu_mstruct.countChildren(); i++) {
if(cu_mstruct.getChild(i)->isUnit()) {
Expand All @@ -3508,7 +3509,7 @@ Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_loca
}
}
if(b) {
Unit *u2 = getBestUnit(cu2, true, convert_to_local_currency);
Unit *u2 = getOptimalUnit(cu2, true, convert_to_local_currency);
b = false;
if(u2->subtype() == SUBTYPE_COMPOSITE_UNIT) {
for(size_t i3 = 1; i3 <= ((CompositeUnit*) u2)->countUnits(); i3++) {
Expand Down Expand Up @@ -3555,7 +3556,8 @@ Unit *Calculator::getBestUnit(Unit *u, bool allow_only_div, bool convert_to_loca
}
return u;
}
MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const EvaluationOptions &eo, bool convert_to_si_units) {
MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const EvaluationOptions &eo, bool convert_to_si_units) {return convertToOptimalUnit(mstruct, eo, convert_to_si_units);}
MathStructure Calculator::convertToOptimalUnit(const MathStructure &mstruct, const EvaluationOptions &eo, bool convert_to_si_units) {
EvaluationOptions eo2 = eo;
//eo2.calculate_functions = false;
eo2.sync_units = false;
Expand Down Expand Up @@ -3583,12 +3585,12 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
} else {
mstruct_new.eval(eo2);
}
mstruct_new = convertToBestUnit(mstruct_new, eo, convert_to_si_units);
mstruct_new = convertToOptimalUnit(mstruct_new, eo, convert_to_si_units);
if(mstruct_new.equals(mstruct, true, true)) return mstruct_new;
} else {
CompositeUnit *cu = new CompositeUnit("", "temporary_composite_convert_to_best_unit");
CompositeUnit *cu = new CompositeUnit("", "temporary_composite_convert_to_optimal_unit");
cu->add(mstruct_new.base()->unit(), mstruct_new.exponent()->number().numerator().intValue());
Unit *u = getBestUnit(cu, false, eo.local_currency_conversion);
Unit *u = getOptimalUnit(cu, false, eo.local_currency_conversion);
if(u == cu) {
delete cu;
return mstruct_new;
Expand Down Expand Up @@ -3668,7 +3670,7 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
bool b = false;
for(size_t i = 0; i < mstruct_new.size(); i++) {
if(mstruct_new.size() > 100 && aborted()) return mstruct;
mstruct_new[i] = convertToBestUnit(mstruct_new[i], eo, convert_to_si_units);
mstruct_new[i] = convertToOptimalUnit(mstruct_new[i], eo, convert_to_si_units);
if(!b && !mstruct_new[i].equals(mstruct[i], true, true)) b = true;
}
if(b) {
Expand All @@ -3679,7 +3681,7 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
}
case STRUCT_UNIT: {
if((!mstruct.unit()->isCurrency() || !eo.local_currency_conversion) && (!convert_to_si_units || mstruct.unit()->isSIUnit())) return mstruct;
Unit *u = getBestUnit(mstruct.unit(), false, eo.local_currency_conversion);
Unit *u = getOptimalUnit(mstruct.unit(), false, eo.local_currency_conversion);
if(u != mstruct.unit()) {
if((u->isSIUnit() || (u->isCurrency() && eo.local_currency_conversion)) && (eo.approximation != APPROXIMATION_EXACT || !mstruct.unit()->hasApproximateRelationTo(u, true))) {
MathStructure mstruct_new = convert(mstruct, u, eo, true);
Expand Down Expand Up @@ -3718,7 +3720,7 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
old_minus = false;
}
} else if(mstruct_old.getChild(i)->size() > 0) {
mstruct_old[i - 1] = convertToBestUnit(mstruct_old[i - 1], eo, convert_to_si_units);
mstruct_old[i - 1] = convertToOptimalUnit(mstruct_old[i - 1], eo, convert_to_si_units);
mstruct_old.childUpdated(i);
if(!mstruct_old[i - 1].equals(mstruct[i - 1], true, true)) child_updated = true;
}
Expand All @@ -3733,9 +3735,9 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
mstruct_new.eval(eo2);
}
if(mstruct_new.type() != STRUCT_MULTIPLICATION) {
mstruct_new = convertToBestUnit(mstruct_new, eo, convert_to_si_units);
mstruct_new = convertToOptimalUnit(mstruct_new, eo, convert_to_si_units);
} else {
CompositeUnit *cu = new CompositeUnit("", "temporary_composite_convert_to_best_unit");
CompositeUnit *cu = new CompositeUnit("", "temporary_composite_convert_to_optimal_unit");
bool b = false;
child_updated = false;
for(size_t i = 1; i <= mstruct_new.countChildren(); i++) {
Expand All @@ -3748,14 +3750,14 @@ MathStructure Calculator::convertToBestUnit(const MathStructure &mstruct, const
cu->add(mstruct_new.getChild(i)->base()->unit(), mstruct_new.getChild(i)->exponent()->number().intValue());
} else if(mstruct_new.getChild(i)->size() > 0) {
MathStructure m_i_old(mstruct_new[i - 1]);
mstruct_new[i - 1] = convertToBestUnit(mstruct_new[i - 1], eo, convert_to_si_units);
mstruct_new[i - 1] = convertToOptimalUnit(mstruct_new[i - 1], eo, convert_to_si_units);
mstruct_new.childUpdated(i);
if(!mstruct_new[i - 1].equals(m_i_old, true, true)) child_updated = true;
}
}
bool is_converted = false;
if(b) {
Unit *u = getBestUnit(cu, false, eo.local_currency_conversion);
Unit *u = getOptimalUnit(cu, false, eo.local_currency_conversion);
if(u != cu) {
if(eo.approximation != APPROXIMATION_EXACT || !cu->hasApproximateRelationTo(u, true)) {
mstruct_new = convert(mstruct_new, u, eo, true);
Expand Down
12 changes: 8 additions & 4 deletions libqalculate/Calculator.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,12 @@ class Calculator {
MathStructure convertTimeOut(string str, Unit *from_unit, Unit *to_unit, int milliseconds, const EvaluationOptions &eo = default_evaluation_options);
MathStructure convert(string str, Unit *from_unit, Unit *to_unit, const EvaluationOptions &eo = default_evaluation_options);
MathStructure convertToBaseUnits(const MathStructure &mstruct, const EvaluationOptions &eo = default_evaluation_options);
/** Deprecated: use getOptimalUnit() */
Unit *getBestUnit(Unit *u, bool allow_only_div = false, bool convert_to_local_currency = true);
Unit *getOptimalUnit(Unit *u, bool allow_only_div = false, bool convert_to_local_currency = true);
/** Deprecated: use convertToOptimalUnit() */
MathStructure convertToBestUnit(const MathStructure &mstruct, const EvaluationOptions &eo = default_evaluation_options, bool convert_to_si_units = true);
MathStructure convertToOptimalUnit(const MathStructure &mstruct, const EvaluationOptions &eo = default_evaluation_options, bool convert_to_si_units = true);
MathStructure convertToCompositeUnit(const MathStructure &mstruct, CompositeUnit *cu, const EvaluationOptions &eo = default_evaluation_options, bool always_convert = true);
MathStructure convertToMixedUnits(const MathStructure &mstruct, const EvaluationOptions &eo = default_evaluation_options);
//@}
Expand Down Expand Up @@ -751,15 +755,15 @@ class Calculator {
* @param all_prefixes If false, prefixes which is not a multiple of thousand (centi, deci, deka, hekto) will be skipped.
* @returns A prefix or NULL if the unit should be left without prefix.
*/
DecimalPrefix *getBestDecimalPrefix(int exp10, int exp = 1, bool all_prefixes = true) const;
DecimalPrefix *getOptimalDecimalPrefix(int exp10, int exp = 1, bool all_prefixes = true) const;
/** Returns the best suited decimal prefix for a value.
*
* @param exp10 Base-10 exponent of the value.
* @param exp The exponent of the unit.
* @param all_prefixes If false, prefixes which is not a multiple of thousand (centi, deci, deka, hekto) will be skipped.
* @returns A prefix or NULL if the unit should be left without prefix.
*/
DecimalPrefix *getBestDecimalPrefix(const Number &exp10, const Number &exp, bool all_prefixes = true) const;
DecimalPrefix *getOptimalDecimalPrefix(const Number &exp10, const Number &exp, bool all_prefixes = true) const;
/** Returns the nearest binary prefix for a value.
*
* @param exp10 Base-2 exponent of the value.
Expand All @@ -773,14 +777,14 @@ class Calculator {
* @param exp The exponent of the unit.
* @returns A prefix or NULL if the unit should be left without prefix.
*/
BinaryPrefix *getBestBinaryPrefix(int exp2, int exp = 1) const;
BinaryPrefix *getOptimalBinaryPrefix(int exp2, int exp = 1) const;
/** Returns the best suited binary prefix for a value.
*
* @param exp10 Base-2 exponent of the value.
* @param exp The exponent of the unit.
* @returns A prefix or NULL if the unit should be left without prefix.
*/
BinaryPrefix *getBestBinaryPrefix(const Number &exp2, const Number &exp) const;
BinaryPrefix *getOptimalBinaryPrefix(const Number &exp2, const Number &exp) const;
/** Add a new prefix to the calculator. */
Prefix *addPrefix(Prefix *p);
/** Used internally. */
Expand Down
5 changes: 2 additions & 3 deletions libqalculate/DataSet.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1103,15 +1103,14 @@ int DataObjectArgument::type() const {return ARGUMENT_TYPE_DATA_OBJECT;}
Argument *DataObjectArgument::copy() const {return new DataObjectArgument(this);}
string DataObjectArgument::print() const {return _("data object");}
string DataObjectArgument::subprintlong() const {
if(!o_data) return print();
string str = _("an object from");
str += " \"";
str += o_data->title();
str += "\"";
DataPropertyIter it;
DataProperty *o = NULL;
if(o_data) {
o = o_data->getFirstProperty(&it);
}
o = o_data->getFirstProperty(&it);
if(o) {
string stmp;
size_t l_last = 0;
Expand Down
Loading

0 comments on commit f367522

Please sign in to comment.