Skip to content

Commit

Permalink
fix #979 wrong result from arithmetic operation with integers and flo…
Browse files Browse the repository at this point in the history
…ats (in progress)
  • Loading branch information
Nelson-numerical-software committed Oct 19, 2023
1 parent 1b61653 commit 74d1097
Show file tree
Hide file tree
Showing 13 changed files with 472 additions and 219 deletions.
31 changes: 13 additions & 18 deletions modules/interpreter/src/cpp/operators/DotLeftDivideOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,33 @@ Evaluator::dotLeftDivideOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}
res = DotLeftDivide(A, B, needToOverload);
Expand Down
32 changes: 14 additions & 18 deletions modules/interpreter/src/cpp/operators/DotRightDivideOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,40 +52,36 @@ Evaluator::dotRightDivideOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}

res = DotRightDivide(A, B, needToOverload);

if (needToOverload) {
Expand Down
31 changes: 13 additions & 18 deletions modules/interpreter/src/cpp/operators/LeftDivideOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,33 @@ Evaluator::leftDivideOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}
res = LeftDivide(A, B, needToOverload);
Expand Down
7 changes: 7 additions & 0 deletions modules/interpreter/src/cpp/operators/MpowerOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "OverloadHelpers.hpp"
#include "OverloadRequired.hpp"
#include "FindCommonType.hpp"
#include "IEEEFP.hpp"
//=============================================================================
namespace Nelson {
//=============================================================================
Expand Down Expand Up @@ -60,6 +61,12 @@ Evaluator::mpowerOperator(const ArrayOfVector& args)
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
auto* ptrB = (double*)B.getDataPointer();
indexType elementCount = B.getElementCount();
bool allIntegerValue = IsIntegerForm(ptrB, elementCount);
if (!allIntegerValue) {
Error(_W("Positive integral powers expected."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
Expand Down
34 changes: 14 additions & 20 deletions modules/interpreter/src/cpp/operators/MtimesOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,42 +51,37 @@ Evaluator::mtimesOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}
res = matrixMultiplication(A, B, needToOverload);

res = matrixMultiplication(A, B, needToOverload);
if (needToOverload) {
bool overloadWasFound = false;
res = callOverloadedFunction(this, NLS_OVERLOAD_ALL_TYPES, args, functionName,
Expand All @@ -95,7 +90,6 @@ Evaluator::mtimesOperator(const ArrayOfVector& args)
OverloadRequired(functionName);
}
}

return res;
}
//=============================================================================
Expand Down
31 changes: 13 additions & 18 deletions modules/interpreter/src/cpp/operators/RightDivideOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,33 @@ Evaluator::rightDivideOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}
res = RightDivide(A, B, needToOverload);
Expand Down
31 changes: 13 additions & 18 deletions modules/interpreter/src/cpp/operators/TimesOperator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,33 @@ Evaluator::timesOperator(const ArrayOfVector& args)
bool needToOverload = false;
ArrayOf A(args[0]);
ArrayOf B(args[1]);

if (A.getDataClass() != B.getDataClass()) {
if (A.isIntegerType()) {
bool isCompatible = (B.getDataClass() == NLS_DOUBLE) && B.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else if (B.isIntegerType()) {
bool isCompatible = (A.getDataClass() == NLS_DOUBLE) && A.isScalar();
if (!isCompatible) {
Error(_W("Integers can only be combined with integers of the same class, or scalar "
"doubles."));
}
A.promoteType(commonType);
B.promoteType(commonType);
} else {
if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
} else if (commonType <= NLS_CHAR) {
NelsonType _commonType = commonType;
if (_commonType == NLS_CHAR) {
_commonType = NLS_DOUBLE;
}
if (_commonType == NLS_DOUBLE && isComplex) {
_commonType = NLS_DCOMPLEX;
}
if (_commonType == NLS_SINGLE && isComplex) {
_commonType = NLS_SCOMPLEX;
}
A.promoteType(_commonType);
B.promoteType(_commonType);
}
}
res = elementWiseMultiplication(A, B, needToOverload);
Expand Down
Loading

0 comments on commit 74d1097

Please sign in to comment.