logic toolbox with logic functions

This commit is contained in:
Joe Crop
2022-12-05 20:07:45 -08:00
parent 1bf164e1e3
commit 42d8fea8c6
23 changed files with 1864 additions and 3 deletions

View File

@@ -97,7 +97,7 @@ public:
AdditionalInformationType additionalInformationType(Poincare::Context * context); AdditionalInformationType additionalInformationType(Poincare::Context * context);
private: private:
static constexpr KDCoordinate k_heightComputationFailureHeight = 50; static constexpr KDCoordinate k_heightComputationFailureHeight = 50;
static constexpr const char * k_maximalIntegerWithAdditionalInformation = "10000000000000000"; static constexpr const char * k_maximalIntegerWithAdditionalInformation = "18446744073709551617"; // 2^64 + 1
void setHeights(KDCoordinate height, KDCoordinate expandedHeight); void setHeights(KDCoordinate height, KDCoordinate expandedHeight);

View File

@@ -81,7 +81,35 @@ const ToolboxMessageTree matricesChildren[] = {
const ToolboxMessageTree vectorsChildren[] = { const ToolboxMessageTree vectorsChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::DotCommandWithArg, I18n::Message::Dot), ToolboxMessageTree::Leaf(I18n::Message::DotCommandWithArg, I18n::Message::Dot),
ToolboxMessageTree::Leaf(I18n::Message::CrossCommandWithArg, I18n::Message::Cross), ToolboxMessageTree::Leaf(I18n::Message::CrossCommandWithArg, I18n::Message::Cross),
ToolboxMessageTree::Leaf(I18n::Message::NormVectorCommandWithArg, I18n::Message::NormVector), ToolboxMessageTree::Leaf(I18n::Message::NormVectorCommandWithArg, I18n::Message::NormVector)
};
const ToolboxMessageTree logicExplicitChildren[] = {
ToolboxMessageTree::Leaf(I18n::Message::LogicalNotExplicitCommandWithArg, I18n::Message::LogicalNot),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftLeftExplicitCommandWithArg, I18n::Message::LogicalShiftLeft),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftRightExplicitCommandWithArg, I18n::Message::LogicalShiftRight),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftRightArithmeticExplicitCommandWithArg, I18n::Message::LogicalShiftRightArithmetic),
ToolboxMessageTree::Leaf(I18n::Message::LogicalRotateLeftExplicitCommandWithArg, I18n::Message::LogicalRotateLeft),
ToolboxMessageTree::Leaf(I18n::Message::LogicalRotateRightExplicitCommandWithArg, I18n::Message::LogicalRotateRight),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitsClearExplicitCommandWithArg, I18n::Message::LogicalBitsClear)};
const ToolboxMessageTree logicChildren[] = {
ToolboxMessageTree::Node(I18n::Message::ExplicitNumberOfBits, logicExplicitChildren),
ToolboxMessageTree::Leaf(I18n::Message::LogicalAndCommandWithArg, I18n::Message::LogicalAnd),
ToolboxMessageTree::Leaf(I18n::Message::LogicalOrCommandWithArg, I18n::Message::LogicalOr),
ToolboxMessageTree::Leaf(I18n::Message::LogicalXorCommandWithArg, I18n::Message::LogicalXor),
ToolboxMessageTree::Leaf(I18n::Message::LogicalNotCommandWithArg, I18n::Message::LogicalNot),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftLeftCommandWithArg, I18n::Message::LogicalShiftLeft),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftRightCommandWithArg, I18n::Message::LogicalShiftRight),
ToolboxMessageTree::Leaf(I18n::Message::LogicalShiftRightArithmeticCommandWithArg, I18n::Message::LogicalShiftRightArithmetic),
ToolboxMessageTree::Leaf(I18n::Message::LogicalRotateLeftCommandWithArg, I18n::Message::LogicalRotateLeft),
ToolboxMessageTree::Leaf(I18n::Message::LogicalRotateRightCommandWithArg, I18n::Message::LogicalRotateRight),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitGetCommandWithArg, I18n::Message::LogicalBitGet),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitSetCommandWithArg, I18n::Message::LogicalBitSet),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitClearCommandWithArg, I18n::Message::LogicalBitClear),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitFlipCommandWithArg, I18n::Message::LogicalBitFlip),
ToolboxMessageTree::Leaf(I18n::Message::LogicalBitsClearCommandWithArg, I18n::Message::LogicalBitsClear),
ToolboxMessageTree::Leaf(I18n::Message::TwosComplementToBitsCommandWithArg, I18n::Message::TwosComplementToBits)
}; };
#if LIST_ARE_DEFINED #if LIST_ARE_DEFINED
@@ -853,6 +881,7 @@ const ToolboxMessageTree menu[] = {
ToolboxMessageTree::Leaf(I18n::Message::RootCommandWithArg, I18n::Message::NthRoot), ToolboxMessageTree::Leaf(I18n::Message::RootCommandWithArg, I18n::Message::NthRoot),
ToolboxMessageTree::Leaf(I18n::Message::LogCommandWithArg, I18n::Message::BasedLogarithm), ToolboxMessageTree::Leaf(I18n::Message::LogCommandWithArg, I18n::Message::BasedLogarithm),
ToolboxMessageTree::Node(I18n::Message::Calculation, calculChildren), ToolboxMessageTree::Node(I18n::Message::Calculation, calculChildren),
ToolboxMessageTree::Node(I18n::Message::Logic, logicChildren),
ToolboxMessageTree::Node(I18n::Message::ComplexNumber, complexChildren), ToolboxMessageTree::Node(I18n::Message::ComplexNumber, complexChildren),
ToolboxMessageTree::Node(I18n::Message::Unit, unitChildren), ToolboxMessageTree::Node(I18n::Message::Unit, unitChildren),
ToolboxMessageTree::Node(I18n::Message::Arithmetic, arithmeticChildren), ToolboxMessageTree::Node(I18n::Message::Arithmetic, arithmeticChildren),

View File

@@ -485,3 +485,29 @@ Rstvt_Water = "1.01·10^3_Ω_m"
Rstvt_Air = "1.00·10^9_Ω_m" Rstvt_Air = "1.00·10^9_Ω_m"
Rstvt_Glass = "5.00·10^14_Ω_m" Rstvt_Glass = "5.00·10^14_Ω_m"
Rstvt_Wood = "1.00·10^3_Ω_m" Rstvt_Wood = "1.00·10^3_Ω_m"
LogicalAnd = "a AND b"
LogicalAndCommandWithArg = "and(a,b)"
LogicalBitClearCommandWithArg = "bclr(a,b)"
LogicalBitFlipCommandWithArg = "bflp(a,b)"
LogicalBitGetCommandWithArg = "bit(a,b)"
LogicalBitSetCommandWithArg = "bset(a,b)"
LogicalBitsClearCommandWithArg = "bic(a,b)"
LogicalBitsClearExplicitCommandWithArg = "bic(a,b,n)"
LogicalNot = "NOT a"
LogicalNotCommandWithArg = "not(a)"
LogicalNotExplicitCommandWithArg = "not(a,n)"
LogicalOr = "a OR b"
LogicalOrCommandWithArg = "or(a,b)"
LogicalShiftLeftCommandWithArg = "sll(a,s)"
LogicalShiftLeftExplicitCommandWithArg = "sll(a,s,n)"
LogicalShiftRightArithmeticCommandWithArg = "sra(a,s)"
LogicalShiftRightArithmeticExplicitCommandWithArg = "sra(a,s,n)"
LogicalShiftRightCommandWithArg = "srl(a,s)"
LogicalShiftRightExplicitCommandWithArg = "srl(a,s,n)"
LogicalRotateLeftCommandWithArg = "rol(a,r)"
LogicalRotateLeftExplicitCommandWithArg = "rol(a,r,n)"
LogicalRotateRightCommandWithArg = "ror(a,r)"
LogicalRotateRightExplicitCommandWithArg = "ror(a,r,n)"
LogicalXor = "a XOR b"
LogicalXorCommandWithArg = "xor(a,r)"
TwosComplementToBitsCommandWithArg = "tc(a,n)"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Hartbaum-Konstante"
MagneticFluxQuantumTag = "Magnetisches Fluss-Quantum" MagneticFluxQuantumTag = "Magnetisches Fluss-Quantum"
ConductanceQuantumTag = "Leitwertquantum" ConductanceQuantumTag = "Leitwertquantum"
CirculationQuantumTag = "Auflage-Quantum" CirculationQuantumTag = "Auflage-Quantum"
Logic = "Logik"
LogicalBitClear = "Bit b in a löschen"
LogicalBitFlip = "Bit b in a umkehren"
LogicalBitGet = "Bit b aus a lesen"
LogicalBitSet = "Bit b in a setzen"
LogicalBitsClear = "a AND NOT b"
LogicalShiftLeft = "Bitverschiebung links von a um s"
LogicalShiftRightArithmetic = "Arithm. Versch. rechts von a um s"
LogicalShiftRight = "Bitverschiebung rechts von a um s"
LogicalRotateLeft = "Rotieren von a um r Bit n. links"
LogicalRotateRight= "Rotieren von a um r Bit n. rechts"
TwosComplementToBits = "Äquivalent im Zweierkomplement"
ExplicitNumberOfBits = "Explizite Bitbreite"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Hartree Constant"
MagneticFluxQuantumTag = "Magnetic Flux Quantum" MagneticFluxQuantumTag = "Magnetic Flux Quantum"
ConductanceQuantumTag = "Conductance Quantum" ConductanceQuantumTag = "Conductance Quantum"
CirculationQuantumTag = "Circulation Quantum" CirculationQuantumTag = "Circulation Quantum"
Logic = "Logic"
LogicalBitClear = "Clear bit b in a"
LogicalBitFlip = "Flip bit b in a"
LogicalBitGet = "Get bit b in a"
LogicalBitSet = "Set bit b in a"
LogicalBitsClear = "Clear a with b [a AND NOT b]"
LogicalShiftLeft = "Logical shift left [a << s]"
LogicalShiftRightArithmetic = "Arithmetic shift right [a >>> s]"
LogicalShiftRight = "Logical shift right [a >> s]"
LogicalRotateLeft = "Rotate r bits of a to the left"
LogicalRotateRight= "Rotate r bits of a to the right"
TwosComplementToBits = "Two's complement equivalent"
ExplicitNumberOfBits = "Explicit number of bits"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Constante de Hartree"
MagneticFluxQuantumTag = "Flujo Magnético Cuántico" MagneticFluxQuantumTag = "Flujo Magnético Cuántico"
ConductanceQuantumTag = "Conductancia Quantum" ConductanceQuantumTag = "Conductancia Quantum"
CirculationQuantumTag = "Circulación Quantum" CirculationQuantumTag = "Circulación Quantum"
Logic = "Lógico"
LogicalBitClear = "Borrar bit número b en a"
LogicalBitFlip = "Voltear el bit número b en a"
LogicalBitGet = "Obtener el bit número b en a"
LogicalBitSet = "Establecer el número de bit b en a"
LogicalBitsClear = "Borrar a con bits en b"
LogicalShiftLeft = "Desplazamiento lógico izquierda"
LogicalShiftRightArithmetic = "Desplazamiento aritmético derecha"
LogicalShiftRight = "Desplazamiento lógico derecha"
LogicalRotateLeft = "Gire r bits de a hacia izquierda"
LogicalRotateRight= "Gire r bits de a hacia derecha"
TwosComplementToBits = "Equivalente en complemento a dos"
ExplicitNumberOfBits = "Número explícito de bits"

View File

@@ -514,3 +514,16 @@ HartreeConstantTag = "Constante de Hartree"
MagneticFluxQuantumTag = "Quantum de Flux Magnétique" MagneticFluxQuantumTag = "Quantum de Flux Magnétique"
ConductanceQuantumTag = "Quantum de Conductance" ConductanceQuantumTag = "Quantum de Conductance"
CirculationQuantumTag = "Quantum de Circulation" CirculationQuantumTag = "Quantum de Circulation"
Logic = "Logic"
LogicalBitClear = "Effacer le bit numéro b dans a"
LogicalBitFlip = "Inverser le bit numéro b dans a"
LogicalBitGet = "Obtenir le bit numéro b dans a"
LogicalBitSet = "Allumer le bit numéro b dans a"
LogicalBitsClear = "Effacer bits b ds a [a AND NOT b]"
LogicalShiftLeft = "Décalage logique gauche [a << s]"
LogicalShiftRightArithmetic = "Décalage arith. droite [a >>> s]"
LogicalShiftRight = "Décalage logique droite [a >> s]"
LogicalRotateLeft = "Rotation gauche de a par r bits"
LogicalRotateRight= "Rotation droite de a par r bits"
TwosComplementToBits = "Equivalent en complément à deux"
ExplicitNumberOfBits = "Nombre indiqué de bits"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Hartree Állandó"
MagneticFluxQuantumTag = "Mágneses Fluxuskvantum" MagneticFluxQuantumTag = "Mágneses Fluxuskvantum"
ConductanceQuantumTag = "Vezetőképesség Kvantum" ConductanceQuantumTag = "Vezetőképesség Kvantum"
CirculationQuantumTag = "Keringési Kvantum" CirculationQuantumTag = "Keringési Kvantum"
Logic = "Logika"
LogicalBitClear = "Tiszta bit b ban ben a"
LogicalBitFlip = "Flip bit b ban ben a"
LogicalBitGet = "Kap bit b ban ben a"
LogicalBitSet = "Készlet bit b ban ben a"
LogicalBitsClear = "Tiszta a val vel b [a AND NOT b]"
LogicalShiftLeft = "Logikai eltolás balra [a << s]"
LogicalShiftRightArithmetic = "Aritmetikai eltolás jobbra [a >>> s]"
LogicalShiftRight = "Logikai eltolás jobbra [a >> s]"
LogicalRotateLeft = "Forog r bitek nak a balra"
LogicalRotateRight= "Forog r bitek nak a jobbra"
TwosComplementToBits = "Kettő komplementere egyenértékű"
ExplicitNumberOfBits = "Explicit bitszám"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Costante di Hartree"
MagneticFluxQuantumTag = "Flusso magnetico quantico" MagneticFluxQuantumTag = "Flusso magnetico quantico"
ConductanceQuantumTag = "Conduttanza quantistica" ConductanceQuantumTag = "Conduttanza quantistica"
CirculationQuantumTag = "Circolazione quantistica" CirculationQuantumTag = "Circolazione quantistica"
Logic = "Logica"
LogicalBitClear = "Cancella il numero di bit b in a"
LogicalBitFlip = "Capovolgere il bit numero b in a"
LogicalBitGet = "Ottieni il bit numero b in a"
LogicalBitSet = "Impostare il numero di bit b in a"
LogicalBitsClear = "Cancella a con b [a AND NOT b]"
LogicalShiftLeft = "Spostamento logico a sinistra"
LogicalShiftRightArithmetic = "Spostamento aritmetico a destra"
LogicalShiftRight = "Spostamento logico a destra"
LogicalRotateLeft = "Ruota r bit di a verso sinistra"
LogicalRotateRight= "Ruota r bit di a verso destra"
TwosComplementToBits = "Equivalente in complemento di due"
ExplicitNumberOfBits = "Numero esplicito di bit"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Hartreeconstante"
MagneticFluxQuantumTag = "Magnetische flux kwantum" MagneticFluxQuantumTag = "Magnetische flux kwantum"
ConductanceQuantumTag = "Kwantumgeleiding" ConductanceQuantumTag = "Kwantumgeleiding"
CirculationQuantumTag = "Kwantumcirculatie" CirculationQuantumTag = "Kwantumcirculatie"
Logic = "Logica"
LogicalBitClear = "Wis bitnummer b in a"
LogicalBitFlip = "Draai bitnummer b om in a"
LogicalBitGet = "Haal bit nummer b op in a"
LogicalBitSet = "Stel bitnummer b in a"
LogicalBitsClear = "Wis a met bits in b [a AND NOT b]"
LogicalShiftLeft = "Logische verschuiving naar links"
LogicalShiftRightArithmetic = "Rekenkundige verschuiving naar rechts"
LogicalShiftRight = "Logische verschuiving naar rechts"
LogicalRotateLeft = "Draai r stukjes a naar links"
LogicalRotateRight= "Draai r stukjes a naar rechts"
TwosComplementToBits = "Tweeën vullen equivalent aan"
ExplicitNumberOfBits = "Expliciet aantal bits"

View File

@@ -510,3 +510,16 @@ HartreeConstantTag = "Constante de Hartree"
MagneticFluxQuantumTag = "Fluxo Magnético Quântico" MagneticFluxQuantumTag = "Fluxo Magnético Quântico"
ConductanceQuantumTag = "Quantum de Conduta" ConductanceQuantumTag = "Quantum de Conduta"
CirculationQuantumTag = "Quantum de Circulação" CirculationQuantumTag = "Quantum de Circulação"
Logic = "Lógica"
LogicalBitClear = "Limpar o bit b em a"
LogicalBitFlip = "Virar o bit em a"
LogicalBitGet = "Obter o bit b em a"
LogicalBitSet = "Definir o bit b em a"
LogicalBitsClear = "Limpar a com b [a AND NOT b]"
LogicalShiftLeft = "Mudar lógica à esquerda"
LogicalShiftRightArithmetic = "Mudar aritmético para a direita"
LogicalShiftRight = "Mudar lógica para a direita"
LogicalRotateLeft = "Girar r bits de a para a esquerda"
LogicalRotateRight= "Girar r bits de a para a direita"
TwosComplementToBits = "Complementar de dois equivalente"
ExplicitNumberOfBits = "Número explícito de bits"

View File

@@ -50,6 +50,7 @@ poincare_src += $(addprefix poincare/src/,\
arc_tangent.cpp \ arc_tangent.cpp \
arithmetic.cpp \ arithmetic.cpp \
based_integer.cpp \ based_integer.cpp \
binary_operation.cpp \
binom_cdf.cpp \ binom_cdf.cpp \
binomial_coefficient.cpp \ binomial_coefficient.cpp \
binomial_distribution_function.cpp \ binomial_distribution_function.cpp \
@@ -188,6 +189,7 @@ tests_src += $(addprefix poincare/test/,\
layout_cursor.cpp\ layout_cursor.cpp\
layout_serialization.cpp\ layout_serialization.cpp\
layout_to_expression.cpp\ layout_to_expression.cpp\
logic.cpp\
parsing.cpp\ parsing.cpp\
print_float.cpp\ print_float.cpp\
print_int.cpp\ print_int.cpp\

View File

@@ -0,0 +1,225 @@
#ifndef POINCARE_BINARY_OPERATION_H
#define POINCARE_BINARY_OPERATION_H
#include <poincare/approximation_helper.h>
#include <poincare/expression.h>
namespace Poincare
{
template<int T>
class BinaryOperationNode final : public ExpressionNode {
public:
// TreeNode
size_t size() const override { return sizeof(BinaryOperationNode); }
int numberOfChildren() const override;
#if POINCARE_TREE_LOG
void logNodeName(std::ostream &stream) const override
{
stream << "BinaryOperation";
}
#endif
// Properties
Type type() const override { return Type::And; }
// Layout
Layout createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
int serialize(char *buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
// Simplification
Expression shallowReduce(ReductionContext reductionContext) override;
LayoutShape leftLayoutShape() const override { return LayoutShape::MoreLetters; };
LayoutShape rightLayoutShape() const override { return LayoutShape::BoundaryPunctuation; }
// Evaluation
Evaluation<float> approximate(SinglePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<float>(approximationContext); }
Evaluation<double> approximate(DoublePrecision p, ApproximationContext approximationContext) const override { return templatedApproximate<double>(approximationContext); }
template <typename U>
Evaluation<U> templatedApproximate(ApproximationContext approximationContext) const {
return Complex<U>::RealUndefined();
}
};
class BinaryOperation final {
public:
static Expression shallowReduceDirect(Expression & e, const ExpressionNode::Type t, ExpressionNode::ReductionContext reductionContext);
};
class And final : public Expression {
public:
And(const BinaryOperationNode<1> *n) : Expression(n) {}
static And Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<And, BinaryOperationNode<1> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("and", 2, &UntypedBuilderTwoChildren<And>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class Or final : public Expression {
public:
Or(const BinaryOperationNode<5> *n) : Expression(n) {}
static Or Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<Or, BinaryOperationNode<5> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("or", 2, &UntypedBuilderTwoChildren<Or>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class Xor final : public Expression {
public:
Xor(const BinaryOperationNode<9> *n) : Expression(n) {}
static Xor Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<Xor, BinaryOperationNode<9> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("xor", 2, &UntypedBuilderTwoChildren<Xor>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class Not final : public Expression {
public:
Not(const BinaryOperationNode<13> *n) : Expression(n) {}
static Not Builder(Expression child1) { return TreeHandle::FixedArityBuilder<Not, BinaryOperationNode<13> >({child1}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("not", 1, &UntypedBuilderOneChild<Not>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class NotExplicit final : public Expression {
public:
NotExplicit(const BinaryOperationNode<14> *n) : Expression(n) {}
static NotExplicit Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<NotExplicit, BinaryOperationNode<14> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("not", 2, &UntypedBuilderTwoChildren<NotExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitClear final : public Expression {
public:
BitClear(const BinaryOperationNode<15> *n) : Expression(n) {}
static BitClear Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<BitClear, BinaryOperationNode<15> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bclr", 2, &UntypedBuilderTwoChildren<BitClear>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitFlip final : public Expression {
public:
BitFlip(const BinaryOperationNode<16> *n) : Expression(n) {}
static BitFlip Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<BitFlip, BinaryOperationNode<16> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bflp", 2, &UntypedBuilderTwoChildren<BitFlip>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitGet final : public Expression {
public:
BitGet(const BinaryOperationNode<17> *n) : Expression(n) {}
static BitGet Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<BitGet, BinaryOperationNode<17> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bit", 2, &UntypedBuilderTwoChildren<BitGet>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitSet final : public Expression {
public:
BitSet(const BinaryOperationNode<18> *n) : Expression(n) {}
static BitSet Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<BitSet, BinaryOperationNode<18> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bset", 2, &UntypedBuilderTwoChildren<BitSet>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitsClear final : public Expression {
public:
BitsClear(const BinaryOperationNode<19> *n) : Expression(n) {}
static BitsClear Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<BitsClear, BinaryOperationNode<19> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bic", 2, &UntypedBuilderTwoChildren<BitsClear>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class BitsClearExplicit final : public Expression {
public:
BitsClearExplicit(const BinaryOperationNode<20> *n) : Expression(n) {}
static BitsClearExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<BitsClearExplicit, BinaryOperationNode<20> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("bic", 3, &UntypedBuilderThreeChildren<BitsClearExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftLogicLeft final : public Expression {
public:
ShiftLogicLeft(const BinaryOperationNode<21> *n) : Expression(n) {}
static ShiftLogicLeft Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<ShiftLogicLeft, BinaryOperationNode<21> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sll", 2, &UntypedBuilderTwoChildren<ShiftLogicLeft>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftLogicLeftExplicit final : public Expression {
public:
ShiftLogicLeftExplicit(const BinaryOperationNode<22> *n) : Expression(n) {}
static ShiftLogicLeftExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<ShiftLogicLeftExplicit, BinaryOperationNode<22> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sll", 3, &UntypedBuilderThreeChildren<ShiftLogicLeftExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftLogicRight final : public Expression {
public:
ShiftLogicRight(const BinaryOperationNode<23> *n) : Expression(n) {}
static ShiftLogicRight Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<ShiftLogicRight, BinaryOperationNode<23> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("srl", 2, &UntypedBuilderTwoChildren<ShiftLogicRight>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftLogicRightExplicit final : public Expression {
public:
ShiftLogicRightExplicit(const BinaryOperationNode<24> *n) : Expression(n) {}
static ShiftLogicRightExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<ShiftLogicRightExplicit, BinaryOperationNode<24> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("srl", 3, &UntypedBuilderThreeChildren<ShiftLogicRightExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftArithmeticRight final : public Expression {
public:
ShiftArithmeticRight(const BinaryOperationNode<25> *n) : Expression(n) {}
static ShiftArithmeticRight Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<ShiftArithmeticRight, BinaryOperationNode<25> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sra", 2, &UntypedBuilderTwoChildren<ShiftArithmeticRight>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class ShiftArithmeticRightExplicit final : public Expression {
public:
ShiftArithmeticRightExplicit(const BinaryOperationNode<26> *n) : Expression(n) {}
static ShiftArithmeticRightExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<ShiftArithmeticRightExplicit, BinaryOperationNode<26> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("sra", 3, &UntypedBuilderThreeChildren<ShiftArithmeticRightExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class RotateLeft final : public Expression {
public:
RotateLeft(const BinaryOperationNode<27> *n) : Expression(n) {}
static RotateLeft Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<RotateLeft, BinaryOperationNode<27> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rol", 2, &UntypedBuilderTwoChildren<RotateLeft>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class RotateLeftExplicit final : public Expression {
public:
RotateLeftExplicit(const BinaryOperationNode<28> *n) : Expression(n) {}
static RotateLeftExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<RotateLeftExplicit, BinaryOperationNode<28> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("rol", 3, &UntypedBuilderThreeChildren<RotateLeftExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class RotateRight final : public Expression {
public:
RotateRight(const BinaryOperationNode<29> *n) : Expression(n) {}
static RotateRight Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<RotateRight, BinaryOperationNode<29> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ror", 2, &UntypedBuilderTwoChildren<RotateRight>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class RotateRightExplicit final : public Expression {
public:
RotateRightExplicit(const BinaryOperationNode<30> *n) : Expression(n) {}
static RotateRightExplicit Builder(Expression child1, Expression child2, Expression child3) { return TreeHandle::FixedArityBuilder<RotateRightExplicit, BinaryOperationNode<30> >({child1, child2, child3}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("ror", 3, &UntypedBuilderThreeChildren<RotateRightExplicit>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
class TwosComplement final : public Expression {
public:
TwosComplement(const BinaryOperationNode<31> *n) : Expression(n) {}
static TwosComplement Builder(Expression child1, Expression child2) { return TreeHandle::FixedArityBuilder<TwosComplement, BinaryOperationNode<31> >({child1, child2}); }
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("tc", 2, &UntypedBuilderTwoChildren<TwosComplement>);
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
};
} // namespace Poincare
#endif

View File

@@ -20,13 +20,21 @@ class Symbol;
class Expression : public TreeHandle { class Expression : public TreeHandle {
friend class AbsoluteValue; friend class AbsoluteValue;
friend class Addition; friend class Addition;
friend class And;
friend class ArcCosine; friend class ArcCosine;
friend class ArcSine; friend class ArcSine;
friend class ArcTangent; friend class ArcTangent;
friend class Arithmetic; friend class Arithmetic;
friend class BasedInteger; friend class BasedInteger;
friend class BinaryOperation;
friend class BinomialCoefficient; friend class BinomialCoefficient;
friend class BinomialDistributionFunction; friend class BinomialDistributionFunction;
friend class BitClear;
friend class BitFlip;
friend class BitGet;
friend class BitsClear;
friend class BitsClearExplicit;
friend class BitSet;
friend class Ceiling; friend class Ceiling;
friend class CommonLogarithm; friend class CommonLogarithm;
template<typename T> template<typename T>
@@ -74,9 +82,12 @@ class Expression : public TreeHandle {
friend class NormCDF; friend class NormCDF;
friend class NormCDF2; friend class NormCDF2;
friend class NormPDF; friend class NormPDF;
friend class Not;
friend class NotExplicit;
friend class NthRoot; friend class NthRoot;
friend class Number; friend class Number;
friend class Opposite; friend class Opposite;
friend class Or;
friend class ParameteredExpression; friend class ParameteredExpression;
friend class Parenthesis; friend class Parenthesis;
friend class PermuteCoefficient; friend class PermuteCoefficient;
@@ -86,9 +97,19 @@ class Expression : public TreeHandle {
friend class Product; friend class Product;
friend class Randint; friend class Randint;
friend class RealPart; friend class RealPart;
friend class RotateLeft;
friend class RotateLeftExplicit;
friend class RotateRight;
friend class RotateRightExplicit;
friend class Round; friend class Round;
friend class Sequence; friend class Sequence;
friend class SequenceNode; friend class SequenceNode;
friend class ShiftArithmeticRight;
friend class ShiftArithmeticRightExplicit;
friend class ShiftLogicLeft;
friend class ShiftLogicLeftExplicit;
friend class ShiftLogicRight;
friend class ShiftLogicRightExplicit;
friend class SignFunction; friend class SignFunction;
friend class Sine; friend class Sine;
friend class SquareRoot; friend class SquareRoot;
@@ -104,11 +125,13 @@ class Expression : public TreeHandle {
friend class Tangent; friend class Tangent;
friend class Trigonometry; friend class Trigonometry;
friend class TrigonometryCheatTable; friend class TrigonometryCheatTable;
friend class TwosComplement;
friend class Unit; friend class Unit;
friend class UnitConvert; friend class UnitConvert;
friend class VectorCross; friend class VectorCross;
friend class VectorDot; friend class VectorDot;
friend class VectorNorm; friend class VectorNorm;
friend class Xor;
friend class AdditionNode; friend class AdditionNode;
friend class DerivativeNode; friend class DerivativeNode;
@@ -119,6 +142,8 @@ class Expression : public TreeHandle {
friend class FunctionNode; friend class FunctionNode;
friend class IntegralNode; friend class IntegralNode;
template<int T> template<int T>
friend class BinaryOperationNode;
template<int T>
friend class LogarithmNode; friend class LogarithmNode;
friend class MatrixNode; friend class MatrixNode;
friend class NaperianLogarithmNode; friend class NaperianLogarithmNode;

View File

@@ -51,9 +51,16 @@ public:
Cosine, Cosine,
Tangent, Tangent,
AbsoluteValue, AbsoluteValue,
And,
ArcCosine, ArcCosine,
ArcSine, ArcSine,
ArcTangent, ArcTangent,
BitClear,
BitFlip,
BitGet,
BitsClear,
BitsClearExplicit,
BitSet,
BinomCDF, BinomCDF,
BinomialCoefficient, BinomialCoefficient,
BinomPDF, BinomPDF,
@@ -87,22 +94,37 @@ public:
NormCDF, NormCDF,
NormCDF2, NormCDF2,
NormPDF, NormPDF,
Not,
NotExplicit,
NthRoot, NthRoot,
Opposite, Opposite,
Or,
Parenthesis, Parenthesis,
PermuteCoefficient, PermuteCoefficient,
Product, Product,
Random, Random,
Randint, Randint,
RealPart, RealPart,
RotateLeft,
RotateLeftExplicit,
RotateRight,
RotateRightExplicit,
Round, Round,
Sequence, Sequence,
ShiftArithmeticRight,
ShiftArithmeticRightExplicit,
ShiftLogicLeft,
ShiftLogicLeftExplicit,
ShiftLogicRight,
ShiftLogicRightExplicit,
SignFunction, SignFunction,
SquareRoot, SquareRoot,
Subtraction, Subtraction,
Sum, Sum,
TwosComplement,
VectorDot, VectorDot,
VectorNorm, VectorNorm,
Xor,
/* When sorting the children of an expression, we assert that the following /* When sorting the children of an expression, we assert that the following
* nodes are at the end of the list : */ * nodes are at the end of the list : */
// - Units // - Units

View File

@@ -66,6 +66,7 @@ public:
Decimal = 10, Decimal = 10,
Hexadecimal = 16, Hexadecimal = 16,
}; };
enum class LogicOperation { And, Or, Xor };
/* Constructors & Destructors */ /* Constructors & Destructors */
static Integer BuildInteger(native_uint_t * digits, uint16_t numberOfDigits, bool negative, bool enableOverflow = false); static Integer BuildInteger(native_uint_t * digits, uint16_t numberOfDigits, bool negative, bool enableOverflow = false);
Integer(native_int_t i = 0); Integer(native_int_t i = 0);
@@ -154,6 +155,20 @@ public:
static IntegerDivision Division(const Integer & numerator, const Integer & denominator); static IntegerDivision Division(const Integer & numerator, const Integer & denominator);
static Integer Power(const Integer & i, const Integer & j); static Integer Power(const Integer & i, const Integer & j);
static Integer Factorial(const Integer & i); static Integer Factorial(const Integer & i);
// logical operations
static Integer LogicalAndOrXor(const Integer &a, const Integer &b, LogicOperation operation, const Integer &num_bits = Integer(32));
static Integer LogicalNot(const Integer &a, const Integer &num_bits = Integer(32));
static Integer LogicalShift(const Integer &a, const Integer &shift, const Integer &num_bits = Integer(32));
static Integer LogicalShiftRightArithmetic(const Integer &a, const Integer &shift, const Integer &num_bits = Integer(32));
static Integer LogicalRotateRight(const Integer &a, const Integer &rotate, const Integer &num_bits = Integer(32));
static Integer LogicalRotateLeft(const Integer &a, const Integer &rotate, const Integer &num_bits = Integer(32));
static Integer LogicalBitsClear(const Integer &a, const Integer &b, const Integer &num_bits = Integer(32));
static Integer LogicalBitGet(const Integer &a, const Integer &bit);
static Integer LogicalBitClear(const Integer &a, const Integer &bit);
static Integer LogicalBitSet(const Integer &a, const Integer &bit);
static Integer LogicalBitFlip(const Integer &a, const Integer &bit);
static Integer Truncate(const Integer &a, const Integer &num_bits);
static Integer TwosComplementToBits(const Integer &a, const Integer &num_bits);
// Derived expression builder // Derived expression builder
static Expression CreateMixedFraction(const Integer & num, const Integer & denom); static Expression CreateMixedFraction(const Integer & num, const Integer & denom);

View File

@@ -7,6 +7,7 @@
#include <poincare/arc_sine.h> #include <poincare/arc_sine.h>
#include <poincare/arc_tangent.h> #include <poincare/arc_tangent.h>
#include <poincare/based_integer.h> #include <poincare/based_integer.h>
#include <poincare/binary_operation.h>
#include <poincare/binom_cdf.h> #include <poincare/binom_cdf.h>
#include <poincare/binomial_coefficient.h> #include <poincare/binomial_coefficient.h>
#include <poincare/binom_pdf.h> #include <poincare/binom_pdf.h>

View File

@@ -0,0 +1,565 @@
#include <poincare/binary_operation.h>
#include <poincare/layout_helper.h>
#include <poincare/serialization_helper.h>
#include <poincare/undefined.h>
#include <poincare/rational.h>
#include <poincare/based_integer.h>
#include <cmath>
namespace Poincare {
constexpr Expression::FunctionHelper And::s_functionHelper;
constexpr Expression::FunctionHelper Or::s_functionHelper;
constexpr Expression::FunctionHelper Xor::s_functionHelper;
constexpr Expression::FunctionHelper Not::s_functionHelper;
constexpr Expression::FunctionHelper NotExplicit::s_functionHelper;
constexpr Expression::FunctionHelper BitClear::s_functionHelper;
constexpr Expression::FunctionHelper BitFlip::s_functionHelper;
constexpr Expression::FunctionHelper BitGet::s_functionHelper;
constexpr Expression::FunctionHelper BitSet::s_functionHelper;
constexpr Expression::FunctionHelper BitsClear::s_functionHelper;
constexpr Expression::FunctionHelper BitsClearExplicit::s_functionHelper;
constexpr Expression::FunctionHelper ShiftLogicLeft::s_functionHelper;
constexpr Expression::FunctionHelper ShiftLogicLeftExplicit::s_functionHelper;
constexpr Expression::FunctionHelper ShiftLogicRight::s_functionHelper;
constexpr Expression::FunctionHelper ShiftLogicRightExplicit::s_functionHelper;
constexpr Expression::FunctionHelper ShiftArithmeticRight::s_functionHelper;
constexpr Expression::FunctionHelper ShiftArithmeticRightExplicit::s_functionHelper;
constexpr Expression::FunctionHelper RotateLeft::s_functionHelper;
constexpr Expression::FunctionHelper RotateLeftExplicit::s_functionHelper;
constexpr Expression::FunctionHelper RotateRight::s_functionHelper;
constexpr Expression::FunctionHelper RotateRightExplicit::s_functionHelper;
constexpr Expression::FunctionHelper TwosComplement::s_functionHelper;
template<> int BinaryOperationNode<1>::numberOfChildren() const { return And::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<5>::numberOfChildren() const { return Or::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<9>::numberOfChildren() const { return Xor::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<13>::numberOfChildren() const { return Not::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<14>::numberOfChildren() const { return NotExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<15>::numberOfChildren() const { return BitClear::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<16>::numberOfChildren() const { return BitFlip::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<17>::numberOfChildren() const { return BitGet::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<18>::numberOfChildren() const { return BitSet::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<19>::numberOfChildren() const { return BitsClear::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<20>::numberOfChildren() const { return BitsClearExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<21>::numberOfChildren() const { return ShiftLogicLeft::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<22>::numberOfChildren() const { return ShiftLogicLeftExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<23>::numberOfChildren() const { return ShiftLogicRight::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<24>::numberOfChildren() const { return ShiftLogicRightExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<25>::numberOfChildren() const { return ShiftArithmeticRight::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<26>::numberOfChildren() const { return ShiftArithmeticRightExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<27>::numberOfChildren() const { return RotateLeft::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<28>::numberOfChildren() const { return RotateLeftExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<29>::numberOfChildren() const { return RotateRight::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<30>::numberOfChildren() const { return RotateRightExplicit::s_functionHelper.numberOfChildren(); }
template<> int BinaryOperationNode<31>::numberOfChildren() const { return TwosComplement::s_functionHelper.numberOfChildren(); }
template<>
Layout BinaryOperationNode<1>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, And::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<5>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, Or::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<9>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, Xor::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<13>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, Not::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<14>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, NotExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<15>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitClear::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<16>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitFlip::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<17>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitGet::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<18>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitSet::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<19>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitsClear::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<20>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, BitsClearExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<21>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftLogicLeft::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<22>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftLogicLeftExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<23>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftLogicRight::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<24>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftLogicRightExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<25>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftArithmeticRight::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<26>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, ShiftArithmeticRightExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<27>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, RotateLeft::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<28>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, RotateLeftExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<29>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, RotateRight::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<30>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, RotateRightExplicit::s_functionHelper.name());
}
template<>
Layout BinaryOperationNode<31>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, TwosComplement::s_functionHelper.name());
}
template<int T>
int BinaryOperationNode<T>::serialize(char *buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits,
T == 31 ? TwosComplement::s_functionHelper.name() :
T == 30 ? RotateRightExplicit::s_functionHelper.name() :
T == 29 ? RotateRight::s_functionHelper.name() :
T == 28 ? RotateLeftExplicit::s_functionHelper.name() :
T == 27 ? RotateLeft::s_functionHelper.name() :
T == 26 ? ShiftArithmeticRightExplicit::s_functionHelper.name() :
T == 25 ? ShiftArithmeticRight::s_functionHelper.name() :
T == 24 ? ShiftLogicRightExplicit::s_functionHelper.name() :
T == 23 ? ShiftLogicRight::s_functionHelper.name() :
T == 22 ? ShiftLogicLeftExplicit::s_functionHelper.name() :
T == 21 ? ShiftLogicLeft::s_functionHelper.name() :
T == 20 ? BitsClearExplicit::s_functionHelper.name() :
T == 19 ? BitsClear::s_functionHelper.name() :
T == 18 ? BitSet::s_functionHelper.name() :
T == 17 ? BitGet::s_functionHelper.name() :
T == 16 ? BitFlip::s_functionHelper.name() :
T == 15 ? BitClear::s_functionHelper.name() :
T == 14 ? NotExplicit::s_functionHelper.name() :
T == 13 ? Not::s_functionHelper.name() :
T == 9 ? Xor::s_functionHelper.name() :
T == 5 ? Or::s_functionHelper.name() :
And::s_functionHelper.name()
);
}
template<>
Expression BinaryOperationNode<1>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return And(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<5>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return Or(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<9>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return Xor(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<13>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return Not(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<14>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return NotExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<15>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitClear(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<16>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitFlip(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<17>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitGet(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<18>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitSet(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<19>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitsClear(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<20>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BitsClearExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<21>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftLogicLeft(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<22>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftLogicLeftExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<23>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftLogicRight(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<24>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftLogicRightExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<25>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftArithmeticRight(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<26>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return ShiftArithmeticRightExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<27>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return RotateLeft(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<28>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return RotateLeftExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<29>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return RotateRight(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<30>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return RotateRightExplicit(this).shallowReduce(reductionContext);
}
template<>
Expression BinaryOperationNode<31>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return TwosComplement(this).shallowReduce(reductionContext);
}
// Check to make sure the the expression is a positive integer
Integer getValidInteger(Expression a) {
if (a.type() != ExpressionNode::Type::Rational) {
return Integer(-1);
}
Rational ar = static_cast<Rational &>(a);
if (!ar.integerDenominator().isOne()) {
return Integer(-1);
}
return ar.signedIntegerNumerator();
}
Expression BinaryOperation::shallowReduceDirect(Expression & e, const ExpressionNode::Type t, ExpressionNode::ReductionContext reductionContext) {
{
e = e.defaultHandleUnitsInChildren();
if (e.isUndefined()) {
return e;
}
}
Integer aq = getValidInteger(e.childAtIndex(0));
Integer bq;
Integer cq;
Integer x;
if(aq.isNegative() && t != ExpressionNode::Type::TwosComplement) {
return Undefined::Builder();
}
if(t != ExpressionNode::Type::Not) {
bq = getValidInteger(e.childAtIndex(1));
if(bq.isNegative()) {
return Undefined::Builder();
}
}
//used for logic shift (right)
Integer bq_neg = Integer::Multiplication(bq, Integer(-1));
switch(t) {
case ExpressionNode::Type::NotExplicit:
case ExpressionNode::Type::TwosComplement:
if(!bq.isLowerThan(Integer(__INT8_MAX__))) {
return Undefined::Builder();
}
break;
default:
break;
}
switch(t) {
case ExpressionNode::Type::BitsClearExplicit:
case ExpressionNode::Type::ShiftLogicLeftExplicit:
case ExpressionNode::Type::ShiftLogicRightExplicit:
case ExpressionNode::Type::ShiftArithmeticRightExplicit:
case ExpressionNode::Type::RotateLeftExplicit:
case ExpressionNode::Type::RotateRightExplicit:
cq = getValidInteger(e.childAtIndex(2));
if(cq.isMinusOne() || !cq.isLowerThan(Integer(__INT8_MAX__))) {
return Undefined::Builder();
}
break;
default:
break;
}
switch (t) {
case ExpressionNode::Type::And:
x = Integer::LogicalAndOrXor(aq, bq, Integer::LogicOperation::And);
break;
case ExpressionNode::Type::Or:
x = Integer::LogicalAndOrXor(aq, bq, Integer::LogicOperation::Or);
break;
case ExpressionNode::Type::Xor:
x = Integer::LogicalAndOrXor(aq, bq, Integer::LogicOperation::Xor);
break;
case ExpressionNode::Type::Not:
x = Integer::LogicalNot(aq);
break;
case ExpressionNode::Type::NotExplicit:
x = Integer::LogicalNot(aq, bq);
break;
case ExpressionNode::Type::BitClear:
x = Integer::LogicalBitClear(aq, bq);
break;
case ExpressionNode::Type::BitFlip:
x = Integer::LogicalBitFlip(aq, bq);
break;
case ExpressionNode::Type::BitGet:
x = Integer::LogicalBitGet(aq, bq);
break;
case ExpressionNode::Type::BitSet:
x = Integer::LogicalBitSet(aq, bq);
break;
case ExpressionNode::Type::BitsClear:
x = Integer::LogicalBitsClear(aq, bq);
break;
case ExpressionNode::Type::BitsClearExplicit:
x = Integer::LogicalBitsClear(aq, bq, cq);
break;
case ExpressionNode::Type::ShiftLogicLeft:
x = Integer::LogicalShift(aq, bq);
break;
case ExpressionNode::Type::ShiftLogicLeftExplicit:
x = Integer::LogicalShift(aq, bq, cq);
break;
case ExpressionNode::Type::ShiftLogicRight:
x = Integer::LogicalShift(aq, bq_neg);
break;
case ExpressionNode::Type::ShiftLogicRightExplicit:
x = Integer::LogicalShift(aq, bq_neg, cq);
break;
case ExpressionNode::Type::ShiftArithmeticRight:
x = Integer::LogicalShiftRightArithmetic(aq, bq);
break;
case ExpressionNode::Type::ShiftArithmeticRightExplicit:
x = Integer::LogicalShiftRightArithmetic(aq, bq, cq);
break;
case ExpressionNode::Type::RotateLeft:
x = Integer::LogicalRotateLeft(aq, bq);
break;
case ExpressionNode::Type::RotateLeftExplicit:
x = Integer::LogicalRotateLeft(aq, bq, cq);
break;
case ExpressionNode::Type::RotateRight:
x = Integer::LogicalRotateRight(aq, bq);
break;
case ExpressionNode::Type::RotateRightExplicit:
x = Integer::LogicalRotateRight(aq, bq, cq);
break;
case ExpressionNode::Type::TwosComplement:
x = Integer::TwosComplementToBits(aq, bq);
break;
default:
break;
}
Expression result = Rational::Builder(x);
e.replaceWithInPlace(result);
return result.shallowReduce(reductionContext);
}
Expression And::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::And, reductionContext);
}
Expression Or::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
Expression e = Expression::defaultShallowReduce();
return BinaryOperation::shallowReduceDirect(e, ExpressionNode::Type::Or, reductionContext);
}
Expression Xor::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::Xor, reductionContext);
}
Expression Not::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::Not, reductionContext);
}
Expression NotExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::NotExplicit, reductionContext);
}
Expression BitClear::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitClear, reductionContext);
}
Expression BitFlip::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitFlip, reductionContext);
}
Expression BitGet::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitGet, reductionContext);
}
Expression BitSet::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitSet, reductionContext);
}
Expression BitsClear::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitsClear, reductionContext);
}
Expression BitsClearExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::BitsClearExplicit, reductionContext);
}
Expression ShiftLogicLeft::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftLogicLeft, reductionContext);
}
Expression ShiftLogicLeftExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftLogicLeftExplicit, reductionContext);
}
Expression ShiftLogicRight::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftLogicRight, reductionContext);
}
Expression ShiftLogicRightExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftLogicRightExplicit, reductionContext);
}
Expression ShiftArithmeticRight::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftArithmeticRight, reductionContext);
}
Expression ShiftArithmeticRightExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::ShiftArithmeticRightExplicit, reductionContext);
}
Expression RotateLeft::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::RotateLeft, reductionContext);
}
Expression RotateLeftExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::RotateLeftExplicit, reductionContext);
}
Expression RotateRight::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::RotateRight, reductionContext);
}
Expression RotateRightExplicit::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::RotateRightExplicit, reductionContext);
}
Expression TwosComplement::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::TwosComplement, reductionContext);
}
template int BinaryOperationNode<1>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<2>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<3>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<4>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<5>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<6>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<7>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<8>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<9>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<10>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<11>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<12>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<13>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<14>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<15>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<16>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<17>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<18>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<19>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<20>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<21>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<22>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<23>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<24>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<25>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<26>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<27>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<28>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<29>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<30>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
template int BinaryOperationNode<31>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
} // namespace Poincare

View File

@@ -22,6 +22,8 @@ extern "C" {
} }
#include <algorithm> #include <algorithm>
#define __INT8_MAX_MINUS_1__ 0x7E
namespace Poincare { namespace Poincare {
/* To compute operations between Integers, we need an array where to store the /* To compute operations between Integers, we need an array where to store the
@@ -452,6 +454,384 @@ Integer Integer::Factorial(const Integer & i) {
return result; return result;
} }
Integer Integer::LogicalAndOrXor(const Integer &a, const Integer &b, LogicOperation operation, const Integer &num_bits)
{
assert(!a.isNegative());
assert(!b.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow() || b.isOverflow())
{
return Overflow(false);
}
uint8_t digits = std::max(a.numberOfDigits(), b.numberOfDigits());
for (size_t i = 0; i < digits; i++)
{
native_uint_t abits = a.numberOfDigits() > i ? a.digit(i) : 0;
native_uint_t bbits = b.numberOfDigits() > i ? b.digit(i) : 0;
switch(operation) {
case LogicOperation::And: s_workingBuffer[i] = abits & bbits; break;
case LogicOperation::Or: s_workingBuffer[i] = abits | bbits; break;
case LogicOperation::Xor: s_workingBuffer[i] = abits ^ bbits; break;
}
}
Integer uint_final = Truncate(BuildInteger(s_workingBuffer, digits, false), num_bits);
return uint_final;
}
Integer Integer::LogicalNot(const Integer &a, const Integer &num_bits)
{
assert(!a.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow())
{
return Overflow(false);
}
uint8_t digits = std::max(a.numberOfDigits(), (uint8_t)std::ceil(num_bits.extractedInt() / 32.0));
for (size_t i = 0; i < digits; i++)
{
native_uint_t abits = a.numberOfDigits() > i ? a.digit(i) : 0;
s_workingBuffer[i] = ~abits;
}
Integer uint_final = Truncate(BuildInteger(s_workingBuffer, digits, false), num_bits);
return uint_final;
}
Integer Integer::LogicalShift(const Integer &a, const Integer &shift, const Integer &num_bits)
{
assert(!a.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow() || shift.isOverflow())
{
return Overflow(false);
}
if (a.isZero())
{
return a;
}
int8_t points = shift.extractedInt();
Integer uint_final = Truncate(a, num_bits);
if (uint_final.isZero())
{
return uint_final;
}
// Sift Left
while (points > 0)
{
uint8_t power = (points >= 31) ? 31 : points;
//multiplyByPowerOf2 prohibits powers greater than 31...
uint_final = uint_final.multiplyByPowerOf2(power);
points -= power;
}
//Shift Right
while (points < 0)
{
uint8_t power = (-points >= 31) ? 31 : -points;
//multiplyByPowerOf2 prohibits powers greater than 31...
uint_final = uint_final.divideByPowerOf2(power);
points += power;
}
return Truncate(uint_final, num_bits);
}
Integer Integer::LogicalShiftRightArithmetic(const Integer &a, const Integer &shift, const Integer &num_bits)
{
assert(!a.isNegative());
assert(!shift.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow() || shift.isOverflow())
{
return Overflow(false);
}
Integer uint_final = Truncate(a, num_bits); // Make sure input is at the correct precision
if (uint_final.isZero() || shift.isZero())
{
return uint_final;
}
Integer num_bits_minus_1 = Subtraction(num_bits, Integer(1));
Integer sign = LogicalBitGet(uint_final, num_bits_minus_1);
uint8_t points = shift.extractedInt();
uint8_t power;
while (points > 0)
{
//multiplyByPowerOf2 prohibits powers greater than 31...
power = (points >= 31) ? 31 : points;
uint_final = uint_final.divideByPowerOf2(power);
points -= power;
}
//only bother sign extending if the sign is negative
if (!sign.isZero())
{
points = shift.extractedInt();
Integer extend = Integer(1);
while (points > 0)
{
power = (points >= 31) ? 31 : points;
extend = extend.multiplyByPowerOf2(power);
points -= power;
}
extend = Subtraction(extend, Integer(1));
points = num_bits.extractedInt() - shift.extractedInt();
while (points > 0)
{
power = (points >= 31) ? 31 : points;
extend = extend.multiplyByPowerOf2(power);
points -= power;
}
uint_final = Addition(uint_final, extend);
}
return Truncate(uint_final, num_bits);
}
Integer Integer::LogicalRotateRight(const Integer &a, const Integer &rotate, const Integer &num_bits)
{
assert(!a.isNegative());
assert(!rotate.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
assert(rotate.isLowerThan(num_bits));
if (a.isOverflow() || rotate.isOverflow())
{
return Overflow(false);
}
Integer uint_final = Truncate(a, num_bits); // Make sure input is at the correct precision
if (uint_final.isZero() || rotate.isZero())
{
return uint_final;
}
Integer num_bits_plus_1 = Addition(num_bits, Integer(1));
Integer rotate_mask = LogicalShift(Integer(1), rotate, num_bits_plus_1);
rotate_mask = Subtraction(rotate_mask, Integer(1));
Integer rotate_word = LogicalAndOrXor(uint_final, rotate_mask, Integer::LogicOperation::And, num_bits);
Integer rotate_neg = multiplication(rotate, Integer(-1));
uint_final = LogicalShift(uint_final, rotate_neg, num_bits);
//only bother adding if the rotate word is non-zero
if (!rotate_word.isZero())
{
Integer num_bits_minus_rotate = Subtraction(num_bits, rotate);
rotate_word = LogicalShift(rotate_word, num_bits_minus_rotate, num_bits);
uint_final = Addition(uint_final, rotate_word);
}
return Truncate(uint_final, num_bits);
}
Integer Integer::LogicalRotateLeft(const Integer &a, const Integer &rotate, const Integer &num_bits)
{
assert(!a.isNegative());
assert(!rotate.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
assert(rotate.isLowerThan(num_bits));
if (a.isOverflow() || rotate.isOverflow())
{
return Overflow(false);
}
Integer uint_final = Truncate(a, num_bits); // Make sure input is at the correct precision
if (uint_final.isZero() || rotate.isZero())
{
return uint_final;
}
Integer num_bits_plus_1 = Addition(num_bits, Integer(1));
Integer rotate_mask = LogicalShift(Integer(1), rotate, num_bits_plus_1);
rotate_mask = Subtraction(rotate_mask, Integer(1));
Integer num_bits_minus_rotate = Subtraction(num_bits, rotate);
rotate_mask = LogicalShift(rotate_mask, num_bits_minus_rotate, num_bits);
Integer rotate_word = LogicalAndOrXor(uint_final, rotate_mask, Integer::LogicOperation::And, num_bits);
Integer num_bits_minus_rotate_neg = multiplication(num_bits_minus_rotate, Integer(-1));
rotate_word = LogicalShift(rotate_word, num_bits_minus_rotate_neg, num_bits);
uint_final = LogicalShift(uint_final, rotate, num_bits);
uint_final = Addition(uint_final, rotate_word);
return Truncate(uint_final, num_bits);
}
Integer Integer::LogicalBitsClear(const Integer &a, const Integer &b, const Integer &num_bits)
{
//aka. BIC instruction (a & ~b)
assert(!a.isNegative());
assert(!b.isNegative());
assert(num_bits.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow() || b.isOverflow())
{
return Overflow(false);
}
Integer b_invert = LogicalNot(b, num_bits);
Integer bic = LogicalAndOrXor(a, b_invert, Integer::LogicOperation::And, num_bits);
return Truncate(bic, num_bits);
}
Integer Integer::LogicalBitGet(const Integer &a, const Integer &bit)
{
// (a >> bit) & 1, return the bit-th bit of a
assert(!a.isNegative());
assert(bit.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow())
{
return Overflow(false);
}
Integer bit_neg = multiplication(bit, Integer(-1));
Integer shifted = LogicalShift(a, bit_neg, Integer(__INT8_MAX_MINUS_1__));
return LogicalAndOrXor(shifted, Integer(1), Integer::LogicOperation::And, Integer(__INT8_MAX_MINUS_1__));
}
Integer Integer::LogicalBitClear(const Integer &a, const Integer &bit)
{
// x = a & ~(1 << bit), clear tha bit-th bit of a;
assert(!a.isNegative());
assert(bit.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow())
{
return Overflow(false);
}
Integer shifted = LogicalShift(Integer(1), bit, Integer(__INT8_MAX_MINUS_1__));
shifted = LogicalNot(shifted, Integer(__INT8_MAX_MINUS_1__));
return LogicalAndOrXor(a, shifted, Integer::LogicOperation::And, Integer(__INT8_MAX_MINUS_1__));
}
Integer Integer::LogicalBitSet(const Integer &a, const Integer &bit)
{
// x = a | (1 << bit), clear tha bit-th bit of a;
assert(!a.isNegative());
assert(bit.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow())
{
return Overflow(false);
}
Integer shifted = LogicalShift(Integer(1), bit, Integer(__INT8_MAX_MINUS_1__));
return LogicalAndOrXor(a, shifted, Integer::LogicOperation::Or, Integer(__INT8_MAX_MINUS_1__));
}
Integer Integer::LogicalBitFlip(const Integer &a, const Integer &bit)
{
// x = a ^ (1 << bit), flip the bit-th bit of a.
assert(!a.isNegative());
assert(bit.isLowerThan(Integer(__INT8_MAX__)));
if (a.isOverflow())
{
return Overflow(false);
}
Integer shifted = LogicalShift(Integer(1), bit, Integer(__INT8_MAX_MINUS_1__));
return LogicalAndOrXor(a, shifted, Integer::LogicOperation::Xor, Integer(__INT8_MAX_MINUS_1__));
}
Integer Integer::Truncate(const Integer &a, const Integer &num_bits)
{
if (a.isZero() || num_bits.isZero())
{
return Integer(0);
}
assert(!num_bits.isNegative());
native_uint_t n = num_bits.extractedInt();
uint8_t num_digits = std::min((uint8_t)a.numberOfDigits(), (uint8_t)(std::ceil(n / 32.0)));
for (size_t i = 0; i < (uint8_t)(std::ceil(n / 32.0)); i++)
{
s_workingBuffer[i] = a.numberOfDigits() > i ? a.digit(i) : 0;
}
for (uint16_t i = num_digits * 32 - 1; i >= n; i--)
{
bool bit_i = (s_workingBuffer[i / 32] & (1 << i)) >> i;
if (bit_i)
{
s_workingBuffer[i / 32] = s_workingBuffer[i / 32] ^ (1 << i); //flip bit
}
}
// clear all zero-valued digits
if (num_digits > 1)
{
bool msb_cleared = true;
for (uint16_t i = num_digits - 1; i > 0; i--)
{
if (s_workingBuffer[i] == 0 && msb_cleared)
{
num_digits--;
msb_cleared = true;
} else {
msb_cleared = false;
}
}
}
Integer uint_final = BuildInteger(s_workingBuffer, num_digits, false);
return uint_final;
}
Integer Integer::TwosComplementToBits(const Integer &a, const Integer &num_bits)
{
if (a.isZero() || num_bits.isZero())
{
return Integer(0);
}
assert(!num_bits.isNegative());
native_uint_t points = num_bits.extractedInt();
//convert to signed bits if needed:
if (a.isNegative())
{
Integer buffer = usum(Integer(0), a, true);
Integer num_bits_in_a = Integer(32*buffer.numberOfDigits());
Integer msb_pointer = Subtraction(num_bits_in_a, Integer(1));
Integer sign = LogicalBitGet(buffer, msb_pointer);
if(sign.isOne() && num_bits_in_a.isLowerThan(num_bits)) {
//sign extend
for (size_t i = 0; i < (uint8_t)(std::ceil(points / 32.0)); i++)
{
s_workingBuffer[i] = buffer.numberOfDigits() > i ? buffer.digit(i) : 4294967295; //4294967295 = all 1's
}
Integer uint_final = BuildInteger(s_workingBuffer, (uint8_t)(std::ceil(points / 32.0)), false);
return Truncate(uint_final, num_bits);
}
return Truncate(buffer, num_bits);
}
//a is positive
Integer msb_pointer = Subtraction(num_bits, Integer(1));
Integer a_truncated = Truncate(a, num_bits);
Integer sign = LogicalBitGet(a_truncated, msb_pointer);
Integer num_bits_plus_1 = Addition(num_bits, Integer(1));
if (sign.isOne())
{
// flip bits back to unsigned from two's comp
Integer bias = LogicalShift(Integer(1), num_bits, num_bits_plus_1);
bias.setNegative(true);
Integer a_negative = Addition(a_truncated, bias);
return a_negative;
}
// a is positive and the msb is 0
return a;
}
Integer Integer::addition(const Integer & a, const Integer & b, bool inverseBNegative, bool oneDigitOverflow) { Integer Integer::addition(const Integer & a, const Integer & b, bool inverseBNegative, bool oneDigitOverflow) {
bool bNegative = (inverseBNegative ? !b.m_negative : b.m_negative); bool bNegative = (inverseBNegative ? !b.m_negative : b.m_negative);
if (a.m_negative == bNegative) { if (a.m_negative == bNegative) {

View File

@@ -98,14 +98,21 @@ private:
&AbsoluteValue::s_functionHelper, &AbsoluteValue::s_functionHelper,
&ArcCosine::s_functionHelper, &ArcCosine::s_functionHelper,
&HyperbolicArcCosine::s_functionHelper, &HyperbolicArcCosine::s_functionHelper,
&And::s_functionHelper,
&ComplexArgument::s_functionHelper, &ComplexArgument::s_functionHelper,
&ArcSine::s_functionHelper, &ArcSine::s_functionHelper,
&HyperbolicArcSine::s_functionHelper, &HyperbolicArcSine::s_functionHelper,
&ArcTangent::s_functionHelper, &ArcTangent::s_functionHelper,
&HyperbolicArcTangent::s_functionHelper, &HyperbolicArcTangent::s_functionHelper,
&BitClear::s_functionHelper,
&BitFlip::s_functionHelper,
&BitsClear::s_functionHelper,
&BitsClearExplicit::s_functionHelper,
&BinomCDF::s_functionHelper, &BinomCDF::s_functionHelper,
&BinomialCoefficient::s_functionHelper, &BinomialCoefficient::s_functionHelper,
&BinomPDF::s_functionHelper, &BinomPDF::s_functionHelper,
&BitGet::s_functionHelper,
&BitSet::s_functionHelper,
&Ceiling::s_functionHelper, &Ceiling::s_functionHelper,
&ConfidenceInterval::s_functionHelper, &ConfidenceInterval::s_functionHelper,
&Conjugate::s_functionHelper, &Conjugate::s_functionHelper,
@@ -135,6 +142,9 @@ private:
&NormCDF::s_functionHelper, &NormCDF::s_functionHelper,
&NormCDF2::s_functionHelper, &NormCDF2::s_functionHelper,
&NormPDF::s_functionHelper, &NormPDF::s_functionHelper,
&Not::s_functionHelper,
&NotExplicit::s_functionHelper,
&Or::s_functionHelper,
&PermuteCoefficient::s_functionHelper, &PermuteCoefficient::s_functionHelper,
&SimplePredictionInterval::s_functionHelper, &SimplePredictionInterval::s_functionHelper,
&PredictionInterval::s_functionHelper, &PredictionInterval::s_functionHelper,
@@ -145,17 +155,29 @@ private:
&RealPart::s_functionHelper, &RealPart::s_functionHelper,
&MatrixRowEchelonForm::s_functionHelper, &MatrixRowEchelonForm::s_functionHelper,
&DivisionRemainder::s_functionHelper, &DivisionRemainder::s_functionHelper,
&RotateLeft::s_functionHelper,
&RotateLeftExplicit::s_functionHelper,
&NthRoot::s_functionHelper, &NthRoot::s_functionHelper,
&RotateRight::s_functionHelper,
&RotateRightExplicit::s_functionHelper,
&Round::s_functionHelper, &Round::s_functionHelper,
&MatrixReducedRowEchelonForm::s_functionHelper, &MatrixReducedRowEchelonForm::s_functionHelper,
&SignFunction::s_functionHelper, &SignFunction::s_functionHelper,
&Sine::s_functionHelper, &Sine::s_functionHelper,
&HyperbolicSine::s_functionHelper, &HyperbolicSine::s_functionHelper,
&ShiftLogicLeft::s_functionHelper,
&ShiftLogicLeftExplicit::s_functionHelper,
&ShiftArithmeticRight::s_functionHelper,
&ShiftArithmeticRightExplicit::s_functionHelper,
&ShiftLogicRight::s_functionHelper,
&ShiftLogicRightExplicit::s_functionHelper,
&Sum::s_functionHelper, &Sum::s_functionHelper,
&Tangent::s_functionHelper, &Tangent::s_functionHelper,
&HyperbolicTangent::s_functionHelper, &HyperbolicTangent::s_functionHelper,
&TwosComplement::s_functionHelper,
&MatrixTrace::s_functionHelper, &MatrixTrace::s_functionHelper,
&MatrixTranspose::s_functionHelper, &MatrixTranspose::s_functionHelper,
&Xor::s_functionHelper,
&SquareRoot::s_functionHelper &SquareRoot::s_functionHelper
}; };
static constexpr const Expression::FunctionHelper * const * s_reservedFunctionsUpperBound = s_reservedFunctions + (sizeof(s_reservedFunctions)/sizeof(Expression::FunctionHelper *)); static constexpr const Expression::FunctionHelper * const * s_reservedFunctionsUpperBound = s_reservedFunctions + (sizeof(s_reservedFunctions)/sizeof(Expression::FunctionHelper *));

View File

@@ -280,9 +280,16 @@ void TreeHandle::release(uint16_t identifier) {
template AbsoluteValue TreeHandle::FixedArityBuilder<AbsoluteValue, AbsoluteValueNode>(const Tuple &); template AbsoluteValue TreeHandle::FixedArityBuilder<AbsoluteValue, AbsoluteValueNode>(const Tuple &);
template AbsoluteValueLayout TreeHandle::FixedArityBuilder<AbsoluteValueLayout, AbsoluteValueLayoutNode>(const Tuple &); template AbsoluteValueLayout TreeHandle::FixedArityBuilder<AbsoluteValueLayout, AbsoluteValueLayoutNode>(const Tuple &);
template Addition TreeHandle::NAryBuilder<Addition, AdditionNode>(const Tuple &); template Addition TreeHandle::NAryBuilder<Addition, AdditionNode>(const Tuple &);
template And TreeHandle::FixedArityBuilder<And, BinaryOperationNode<1> >(const Tuple &);
template ArcCosine TreeHandle::FixedArityBuilder<ArcCosine, ArcCosineNode>(const Tuple &); template ArcCosine TreeHandle::FixedArityBuilder<ArcCosine, ArcCosineNode>(const Tuple &);
template ArcSine TreeHandle::FixedArityBuilder<ArcSine, ArcSineNode>(const Tuple &); template ArcSine TreeHandle::FixedArityBuilder<ArcSine, ArcSineNode>(const Tuple &);
template ArcTangent TreeHandle::FixedArityBuilder<ArcTangent, ArcTangentNode>(const Tuple &); template ArcTangent TreeHandle::FixedArityBuilder<ArcTangent, ArcTangentNode>(const Tuple &);
template BitClear TreeHandle::FixedArityBuilder<BitClear, BinaryOperationNode<15> >(const Tuple &);
template BitFlip TreeHandle::FixedArityBuilder<BitFlip, BinaryOperationNode<16> >(const Tuple &);
template BitGet TreeHandle::FixedArityBuilder<BitGet, BinaryOperationNode<17> >(const Tuple &);
template BitsClear TreeHandle::FixedArityBuilder<BitsClear, BinaryOperationNode<19> >(const Tuple &);
template BitsClearExplicit TreeHandle::FixedArityBuilder<BitsClearExplicit, BinaryOperationNode<20> >(const Tuple &);
template BitSet TreeHandle::FixedArityBuilder<BitSet, BinaryOperationNode<18> >(const Tuple &);
template BinomCDF TreeHandle::FixedArityBuilder<BinomCDF, BinomCDFNode>(const Tuple &); template BinomCDF TreeHandle::FixedArityBuilder<BinomCDF, BinomCDFNode>(const Tuple &);
template BinomialCoefficient TreeHandle::FixedArityBuilder<BinomialCoefficient, BinomialCoefficientNode>(const Tuple &); template BinomialCoefficient TreeHandle::FixedArityBuilder<BinomialCoefficient, BinomialCoefficientNode>(const Tuple &);
template BinomialCoefficientLayout TreeHandle::FixedArityBuilder<BinomialCoefficientLayout, BinomialCoefficientLayoutNode>(const Tuple &); template BinomialCoefficientLayout TreeHandle::FixedArityBuilder<BinomialCoefficientLayout, BinomialCoefficientLayoutNode>(const Tuple &);
@@ -345,8 +352,11 @@ template NaperianLogarithm TreeHandle::FixedArityBuilder<NaperianLogarithm, Nape
template NormCDF TreeHandle::FixedArityBuilder<NormCDF, NormCDFNode>(const Tuple &); template NormCDF TreeHandle::FixedArityBuilder<NormCDF, NormCDFNode>(const Tuple &);
template NormCDF2 TreeHandle::FixedArityBuilder<NormCDF2, NormCDF2Node>(const Tuple &); template NormCDF2 TreeHandle::FixedArityBuilder<NormCDF2, NormCDF2Node>(const Tuple &);
template NormPDF TreeHandle::FixedArityBuilder<NormPDF, NormPDFNode>(const Tuple &); template NormPDF TreeHandle::FixedArityBuilder<NormPDF, NormPDFNode>(const Tuple &);
template Not TreeHandle::FixedArityBuilder<Not, BinaryOperationNode<13> >(const Tuple &);
template NotExplicit TreeHandle::FixedArityBuilder<NotExplicit, BinaryOperationNode<14> >(const Tuple &);
template NthRoot TreeHandle::FixedArityBuilder<NthRoot, NthRootNode>(const Tuple &); template NthRoot TreeHandle::FixedArityBuilder<NthRoot, NthRootNode>(const Tuple &);
template Opposite TreeHandle::FixedArityBuilder<Opposite, OppositeNode>(const Tuple &); template Opposite TreeHandle::FixedArityBuilder<Opposite, OppositeNode>(const Tuple &);
template Or TreeHandle::FixedArityBuilder<Or, BinaryOperationNode<5> >(const Tuple &);
template Parenthesis TreeHandle::FixedArityBuilder<Parenthesis, ParenthesisNode>(const Tuple &); template Parenthesis TreeHandle::FixedArityBuilder<Parenthesis, ParenthesisNode>(const Tuple &);
template PermuteCoefficient TreeHandle::FixedArityBuilder<PermuteCoefficient, PermuteCoefficientNode>(const Tuple &); template PermuteCoefficient TreeHandle::FixedArityBuilder<PermuteCoefficient, PermuteCoefficientNode>(const Tuple &);
template Power TreeHandle::FixedArityBuilder<Power, PowerNode>(const Tuple &); template Power TreeHandle::FixedArityBuilder<Power, PowerNode>(const Tuple &);
@@ -358,7 +368,17 @@ template Random TreeHandle::FixedArityBuilder<Random, RandomNode>(const Tuple &)
template RealPart TreeHandle::FixedArityBuilder<RealPart, RealPartNode>(const Tuple &); template RealPart TreeHandle::FixedArityBuilder<RealPart, RealPartNode>(const Tuple &);
template RightParenthesisLayout TreeHandle::FixedArityBuilder<RightParenthesisLayout, RightParenthesisLayoutNode>(const Tuple &); template RightParenthesisLayout TreeHandle::FixedArityBuilder<RightParenthesisLayout, RightParenthesisLayoutNode>(const Tuple &);
template RightSquareBracketLayout TreeHandle::FixedArityBuilder<RightSquareBracketLayout, RightSquareBracketLayoutNode>(const Tuple &); template RightSquareBracketLayout TreeHandle::FixedArityBuilder<RightSquareBracketLayout, RightSquareBracketLayoutNode>(const Tuple &);
template RotateLeft TreeHandle::FixedArityBuilder<RotateLeft, BinaryOperationNode<27> >(const Tuple &);
template RotateLeftExplicit TreeHandle::FixedArityBuilder<RotateLeftExplicit, BinaryOperationNode<28> >(const Tuple &);
template RotateRight TreeHandle::FixedArityBuilder<RotateRight, BinaryOperationNode<29> >(const Tuple &);
template RotateRightExplicit TreeHandle::FixedArityBuilder<RotateRightExplicit, BinaryOperationNode<30> >(const Tuple &);
template Round TreeHandle::FixedArityBuilder<Round, RoundNode>(const Tuple &); template Round TreeHandle::FixedArityBuilder<Round, RoundNode>(const Tuple &);
template ShiftArithmeticRight TreeHandle::FixedArityBuilder<ShiftArithmeticRight, BinaryOperationNode<25> >(const Tuple &);
template ShiftArithmeticRightExplicit TreeHandle::FixedArityBuilder<ShiftArithmeticRightExplicit, BinaryOperationNode<26> >(const Tuple &);
template ShiftLogicLeft TreeHandle::FixedArityBuilder<ShiftLogicLeft, BinaryOperationNode<21> >(const Tuple &);
template ShiftLogicLeftExplicit TreeHandle::FixedArityBuilder<ShiftLogicLeftExplicit, BinaryOperationNode<22> >(const Tuple &);
template ShiftLogicRight TreeHandle::FixedArityBuilder<ShiftLogicRight, BinaryOperationNode<23> >(const Tuple &);
template ShiftLogicRightExplicit TreeHandle::FixedArityBuilder<ShiftLogicRightExplicit, BinaryOperationNode<24> >(const Tuple &);
template SignFunction TreeHandle::FixedArityBuilder<SignFunction, SignFunctionNode>(const Tuple &); template SignFunction TreeHandle::FixedArityBuilder<SignFunction, SignFunctionNode>(const Tuple &);
template SimplePredictionInterval TreeHandle::FixedArityBuilder<SimplePredictionInterval, SimplePredictionIntervalNode>(const Tuple &); template SimplePredictionInterval TreeHandle::FixedArityBuilder<SimplePredictionInterval, SimplePredictionIntervalNode>(const Tuple &);
template Sine TreeHandle::FixedArityBuilder<Sine, SineNode>(const Tuple &); template Sine TreeHandle::FixedArityBuilder<Sine, SineNode>(const Tuple &);
@@ -377,5 +397,6 @@ template VectorNorm TreeHandle::FixedArityBuilder<VectorNorm, VectorNormNode>(co
template VectorNormLayout TreeHandle::FixedArityBuilder<VectorNormLayout, VectorNormLayoutNode>(const Tuple &); template VectorNormLayout TreeHandle::FixedArityBuilder<VectorNormLayout, VectorNormLayoutNode>(const Tuple &);
template VectorLayout TreeHandle::FixedArityBuilder<VectorLayout, VectorLayoutNode>(const Tuple &); template VectorLayout TreeHandle::FixedArityBuilder<VectorLayout, VectorLayoutNode>(const Tuple &);
template MatrixLayout TreeHandle::NAryBuilder<MatrixLayout, MatrixLayoutNode>(const Tuple &); template MatrixLayout TreeHandle::NAryBuilder<MatrixLayout, MatrixLayoutNode>(const Tuple &);
template TwosComplement TreeHandle::FixedArityBuilder<TwosComplement, BinaryOperationNode<31> >(const Tuple &);
template Xor TreeHandle::FixedArityBuilder<Xor, BinaryOperationNode<9> >(const Tuple &);
} }

402
poincare/test/logic.cpp Normal file
View File

@@ -0,0 +1,402 @@
#include "helper.h"
using namespace Poincare;
static inline void assert_equal(const Integer i, const Integer j)
{
quiz_assert(Integer::NaturalOrder(i, j) == 0);
}
QUIZ_CASE(poincare_logic_xor_compare)
{
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_FFFF_FFFF = Integer("8589934591");
Integer h1_0000_0000 = Integer("4294967296");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(1), Integer::LogicOperation::Xor), Integer(14));
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(0), Integer::LogicOperation::Xor), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(15), Integer::LogicOperation::Xor), Integer(15));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, Integer(0), Integer::LogicOperation::Xor), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), hFFFF_FFFF, Integer::LogicOperation::Xor), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(0), Integer::LogicOperation::Xor), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(33)), h1_0000_0000);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(33)), h1_FFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(15)), Integer(32767));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(8)), Integer(255));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(4)), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(1)), Integer(1));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(0)), Integer(0));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF_FFFF_FFFF, h0000_FFFF_FFFF_0000, Integer::LogicOperation::Xor, Integer(64)), hFFFF_0000_0000_FFFF);
assert_equal(Integer::LogicalAndOrXor(h0000_FFFF_FFFF_0000, hFFFF_FFFF_FFFF_FFFF, Integer::LogicOperation::Xor, Integer(65)), hFFFF_0000_0000_FFFF);
}
QUIZ_CASE(poincare_logic_or_compare)
{
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_FFFF_FFFF = Integer("8589934591");
Integer h1_0000_0000 = Integer("4294967296");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(1), Integer::LogicOperation::Or), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(0), Integer::LogicOperation::Or), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(15), Integer::LogicOperation::Or), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(15), Integer::LogicOperation::Or), Integer(15));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, Integer(0), Integer::LogicOperation::Or), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), hFFFF_FFFF, Integer::LogicOperation::Or), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, hFFFF_FFFF, Integer::LogicOperation::Or), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(0), Integer::LogicOperation::Or), Integer(0));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_0000_0000, Integer::LogicOperation::Or), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(33)), h1_FFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_0000_0000, Integer::LogicOperation::Or, Integer(33)), h1_0000_0000);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(15)), Integer(32767));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(8)), Integer(255));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(4)), Integer(15));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(1)), Integer(1));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::Or, Integer(0)), Integer(0));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF_FFFF_FFFF, h0000_FFFF_FFFF_0000, Integer::LogicOperation::Or, Integer(64)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(h0000_FFFF_FFFF_0000, hFFFF_0000_0000_FFFF, Integer::LogicOperation::Or, Integer(65)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(h0000_FFFF_FFFF_0000, Integer(0), Integer::LogicOperation::Or, Integer(65)), h0000_FFFF_FFFF_0000);
}
QUIZ_CASE(poincare_logic_and_compare)
{
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_FFFF_FFFF = Integer("8589934591");
Integer h1_0000_0000 = Integer("4294967296");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(1), Integer::LogicOperation::And), Integer(1));
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(0), Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(15), Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(Integer(15), Integer(15), Integer::LogicOperation::And), Integer(15));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, Integer(0), Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(Integer(0), hFFFF_FFFF, Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, hFFFF_FFFF, Integer::LogicOperation::And), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_FFFF_FFFF, Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), Integer(0), Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_0000_0000, Integer::LogicOperation::And), Integer(0));
assert_equal(Integer::LogicalAndOrXor(h1_0000_0000, h1_0000_0000, Integer::LogicOperation::And), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(33)), hFFFF_FFFF);
assert_equal(Integer::LogicalAndOrXor(Integer(0), h1_0000_0000, Integer::LogicOperation::And, Integer(33)), Integer(0));
assert_equal(Integer::LogicalAndOrXor(h1_0000_0000, h1_0000_0000, Integer::LogicOperation::And, Integer(33)), h1_0000_0000);
assert_equal(Integer::LogicalAndOrXor(h1_0000_0000, h1_0000_0000, Integer::LogicOperation::And, Integer(34)), h1_0000_0000);
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(15)), Integer(32767));
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(8)), Integer(255));
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(4)), Integer(15));
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(1)), Integer(1));
assert_equal(Integer::LogicalAndOrXor(h1_FFFF_FFFF, h1_FFFF_FFFF, Integer::LogicOperation::And, Integer(0)), Integer(0));
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF_FFFF_FFFF, h0000_FFFF_FFFF_0000, Integer::LogicOperation::And, Integer(64)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalAndOrXor(hFFFF_FFFF_FFFF_FFFF, h0000_FFFF_FFFF_0000, Integer::LogicOperation::And, Integer(90)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalAndOrXor(h0000_FFFF_FFFF_0000, hFFFF_0000_0000_FFFF, Integer::LogicOperation::And, Integer(65)), Integer(0));
assert_equal(Integer::LogicalAndOrXor(h0000_FFFF_FFFF_0000, hFFFF_FFFF_FFFF_FFFF, Integer::LogicOperation::And, Integer(65)), h0000_FFFF_FFFF_0000);
}
QUIZ_CASE(poincare_logic_not_compare)
{
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_FFFF_FFFF = Integer("8589934591");
Integer h1_0000_0000 = Integer("4294967296");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalNot(hFFFF_FFFF), Integer(0));
assert_equal(Integer::LogicalNot(Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalNot(h1_FFFF_FFFF), Integer(0));
assert_equal(Integer::LogicalNot(h1_0000_0000), hFFFF_FFFF);
//explicit num_bits
assert_equal(Integer::LogicalNot(hFFFF_FFFF, Integer(33)), h1_0000_0000);
assert_equal(Integer::LogicalNot(Integer(0), Integer(33)), h1_FFFF_FFFF);
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(33)), hFFFF_FFFF);
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(15)), Integer(32767));
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(8)), Integer(255));
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(4)), Integer(15));
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(1)), Integer(1));
assert_equal(Integer::LogicalNot(h1_0000_0000, Integer(0)), Integer(0));
assert_equal(Integer::LogicalNot(h0000_FFFF_FFFF_0000, Integer(64)), hFFFF_0000_0000_FFFF);
assert_equal(Integer::LogicalNot(hFFFF_0000_0000_FFFF, Integer(64)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalNot(hFFFF_FFFF_FFFF_FFFF, Integer(64)), Integer(0));
assert_equal(Integer::LogicalNot(hFFFF_FFFF_FFFF_FFFF, Integer(51)), Integer(0));
assert_equal(Integer::LogicalNot(Integer(0), Integer(64)), hFFFF_FFFF_FFFF_FFFF);
}
QUIZ_CASE(poincare_logic_sll_compare)
{
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer h1_0000_0000_0000_0000 = Integer("18446744073709551616");
assert_equal(Integer::LogicalShift(hFFFF_FFFF, Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalShift(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalShift(Integer(0), Integer(36)), Integer(0));
assert_equal(Integer::LogicalShift(h1_0000_0000, Integer(32)), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalShift(Integer(1), Integer(32), Integer(33)), h1_0000_0000);
assert_equal(Integer::LogicalShift(h0000_FFFF_FFFF_0000, Integer(16), Integer(64)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalShift(h0000_FFFF_FFFF_0000, Integer(16), Integer(65)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalShift(Integer(1), Integer(64), Integer(65)), h1_0000_0000_0000_0000);
}
QUIZ_CASE(poincare_logic_srl_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
assert_equal(Integer::LogicalShift(hFFFF_FFFF, Integer(-0)), hFFFF_FFFF);
assert_equal(Integer::LogicalShift(Integer(0), Integer(-6)), Integer(0));
assert_equal(Integer::LogicalShift(Integer(0), Integer(-36)), Integer(0));
assert_equal(Integer::LogicalShift(h1_0000_0000, Integer(-32)), Integer(0));
assert_equal(Integer::LogicalShift(hFFFF_FFFF, Integer(-32)), Integer(0));
assert_equal(Integer::LogicalShift(hFFFF_FFFF, Integer(-31)), Integer(1));
assert_equal(Integer::LogicalShift(hFFFF_FFFF, Integer(-30)), Integer(3));
//explicit num_bits
assert_equal(Integer::LogicalShift(h0000_FFFF_FFFF_0000, Integer(-32), Integer(33)), Integer(1));
assert_equal(Integer::LogicalShift(h0000_FFFF_FFFF_0000, Integer(-32), Integer(64)), hFFFF);
assert_equal(Integer::LogicalShift(h0000_FFFF_FFFF_0000, Integer(-32), Integer(66)), hFFFF);
}
QUIZ_CASE(poincare_logic_sra_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF_FFFF, Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalShiftRightArithmetic(Integer(0), Integer(36)), Integer(0));
assert_equal(Integer::LogicalShiftRightArithmetic(h1_0000_0000, Integer(32)), Integer(0));
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF_FFFF, Integer(32)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF_FFFF, Integer(3)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF_FFFF, Integer(30)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF, Integer(14)), Integer(3));
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF, Integer(15)), Integer(1));
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF, Integer(16)), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalShiftRightArithmetic(h0000_FFFF_FFFF_0000, Integer(16), Integer(64)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(h0000_FFFF_FFFF_0000, Integer(16), Integer(50)), hFFFF_FFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(h0000_FFFF_FFFF_0000, Integer(32), Integer(64)), hFFFF);
assert_equal(Integer::LogicalShiftRightArithmetic(h0000_FFFF_FFFF_0000, Integer(32), Integer(4)), Integer(0));
assert_equal(Integer::LogicalShiftRightArithmetic(hFFFF_FFFF_0000_0000, Integer(32), Integer(64)), hFFFF_FFFF_FFFF_FFFF);
}
QUIZ_CASE(poincare_logic_bit_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
for (uint8_t i = 0; i < 32; i++)
{
assert_equal(Integer::LogicalBitGet(hFFFF_FFFF, Integer(i)), Integer(1));
assert_equal(Integer::LogicalBitGet(h1_0000_0000, Integer(i)), Integer(0));
}
assert_equal(Integer::LogicalBitGet(h1_0000_0000, Integer(32)), Integer(1));
assert_equal(Integer::LogicalBitGet(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalBitGet(h0000_FFFF_FFFF_0000, Integer(32)), Integer(1));
assert_equal(Integer::LogicalBitGet(h0000_FFFF_FFFF_0000, Integer(33)), Integer(1));
assert_equal(Integer::LogicalBitGet(h0000_FFFF_FFFF_0000, Integer(47)), Integer(1));
assert_equal(Integer::LogicalBitGet(h0000_FFFF_FFFF_0000, Integer(48)), Integer(0));
}
QUIZ_CASE(poincare_logic_ror_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(1)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(2)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(3)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(16)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(30)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF, Integer(31)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(Integer(0), Integer(0)), Integer(0));
assert_equal(Integer::LogicalRotateRight(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalRotateRight(h1_0000_0000, Integer(31)), Integer(0));
assert_equal(Integer::LogicalRotateRight(h1_0000_0000, Integer(3)), Integer(0));
assert_equal(Integer::LogicalRotateRight(hFFFF, Integer(16)), hFFFF_0000);
assert_equal(Integer::LogicalRotateRight(Integer(2), Integer(1)), Integer(1));
assert_equal(Integer::LogicalRotateRight(Integer(6), Integer(1)), Integer(3));
//explicit num_bits
assert_equal(Integer::LogicalRotateRight(h0000_FFFF_FFFF_0000, Integer(16), Integer(64)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(h0000_FFFF_FFFF_0000, Integer(16), Integer(50)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateRight(h0000_FFFF_FFFF_0000, Integer(32), Integer(64)), hFFFF_0000_0000_FFFF);
assert_equal(Integer::LogicalRotateRight(hFFFF_FFFF_0000_0000, Integer(16), Integer(64)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalRotateRight(h0000_FFFF_FFFF_0000, Integer(48), Integer(64)), hFFFF_FFFF_0000_0000);
}
QUIZ_CASE(poincare_logic_rol_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(1)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(2)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(3)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(16)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(30)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(31)), hFFFF_FFFF);
assert_equal(Integer::LogicalRotateLeft(Integer(0), Integer(0)), Integer(0));
assert_equal(Integer::LogicalRotateLeft(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalRotateLeft(h1_0000_0000, Integer(31)), Integer(0));
assert_equal(Integer::LogicalRotateLeft(h1_0000_0000, Integer(3)), Integer(0));
assert_equal(Integer::LogicalRotateLeft(hFFFF, Integer(16)), hFFFF_0000);
assert_equal(Integer::LogicalRotateLeft(Integer(2), Integer(1)), Integer(4));
assert_equal(Integer::LogicalRotateLeft(Integer(6), Integer(1)), Integer(12));
//explicit num_bits
assert_equal(Integer::LogicalRotateLeft(h0000_FFFF_FFFF_0000, Integer(16), Integer(64)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF, Integer(16), Integer(50)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalRotateLeft(h0000_FFFF_FFFF_0000, Integer(32), Integer(64)), hFFFF_0000_0000_FFFF);
assert_equal(Integer::LogicalRotateLeft(hFFFF_FFFF_0000_0000, Integer(16), Integer(64)), hFFFF_0000_0000_FFFF);
assert_equal(Integer::LogicalRotateLeft(h0000_FFFF_FFFF_0000, Integer(48), Integer(64)), hFFFF_FFFF);
}
QUIZ_CASE(poincare_logic_bic_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF, Integer(0)), hFFFF_FFFF);
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF, hFFFF), hFFFF_0000);
assert_equal(Integer::LogicalBitsClear(hFFFF_0000, hFFFF), hFFFF_0000);
assert_equal(Integer::LogicalBitsClear(Integer(7), Integer(2)), Integer(5));
assert_equal(Integer::LogicalBitsClear(Integer(0), Integer(0)), Integer(0));
assert_equal(Integer::LogicalBitsClear(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalBitsClear(h1_0000_0000, Integer(31)), Integer(0));
assert_equal(Integer::LogicalBitsClear(h1_0000_0000, Integer(3)), Integer(0));
//explicit num_bits
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF_0000_0000, hFFFF_FFFF, Integer(64)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF_FFFF_FFFF, hFFFF_FFFF_0000_0000, Integer(64)), hFFFF_FFFF);
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF_FFFF_FFFF, hFFFF_0000_0000_FFFF, Integer(64)), h0000_FFFF_FFFF_0000);
assert_equal(Integer::LogicalBitsClear(hFFFF_FFFF_FFFF_FFFF, h0000_FFFF_FFFF_0000, Integer(64)), hFFFF_0000_0000_FFFF);
}
QUIZ_CASE(poincare_logic_bclr_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h7FFF_FFFF_FFFF_FFFF = Integer("9223372036854775807");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalBitClear(Integer(1), Integer(0)), Integer(0));
assert_equal(Integer::LogicalBitClear(Integer(7), Integer(2)), Integer(3));
assert_equal(Integer::LogicalBitClear(Integer(0), Integer(0)), Integer(0));
assert_equal(Integer::LogicalBitClear(Integer(0), Integer(6)), Integer(0));
assert_equal(Integer::LogicalBitClear(h1_0000_0000, Integer(32)), Integer(0));
assert_equal(Integer::LogicalBitClear(h1_0000_0000, Integer(3)), h1_0000_0000);
assert_equal(Integer::LogicalBitClear(hFFFF_FFFF_0000_0000, Integer(64)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalBitClear(hFFFF_FFFF_FFFF_FFFF, Integer(64)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::LogicalBitClear(hFFFF_FFFF_FFFF_FFFF, Integer(63)), h7FFF_FFFF_FFFF_FFFF);
}
QUIZ_CASE(poincare_logic_bset_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h7FFF_FFFF_FFFF_FFFF = Integer("9223372036854775807");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalBitSet(Integer(1), Integer(0)), Integer(1));
assert_equal(Integer::LogicalBitSet(Integer(0), Integer(0)), Integer(1));
assert_equal(Integer::LogicalBitSet(Integer(3), Integer(2)), Integer(7));
assert_equal(Integer::LogicalBitSet(Integer(0), Integer(8)), Integer(256));
assert_equal(Integer::LogicalBitSet(Integer(0), Integer(32)), h1_0000_0000);
assert_equal(Integer::LogicalBitSet(hFFFF_FFFF_0000_0000, Integer(63)), hFFFF_FFFF_0000_0000);
assert_equal(Integer::LogicalBitSet(hFFFF_FFFF_FFFF_FFFF, Integer(60)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::LogicalBitSet(h7FFF_FFFF_FFFF_FFFF, Integer(63)), hFFFF_FFFF_FFFF_FFFF);
}
QUIZ_CASE(poincare_logic_bflip_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h7FFF_FFFF_FFFF_FFFF = Integer("9223372036854775807");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::LogicalBitFlip(Integer(1), Integer(0)), Integer(0));
assert_equal(Integer::LogicalBitFlip(Integer(0), Integer(0)), Integer(1));
assert_equal(Integer::LogicalBitFlip(Integer(3), Integer(2)), Integer(7));
assert_equal(Integer::LogicalBitFlip(Integer(7), Integer(2)), Integer(3));
assert_equal(Integer::LogicalBitFlip(Integer(1), Integer(8)), Integer(257));
assert_equal(Integer::LogicalBitFlip(Integer(257), Integer(8)), Integer(1));
assert_equal(Integer::LogicalBitFlip(Integer(0), Integer(32)), h1_0000_0000);
assert_equal(Integer::LogicalBitFlip(h1_0000_0000, Integer(32)), Integer(0));
assert_equal(Integer::LogicalBitFlip(h7FFF_FFFF_FFFF_FFFF, Integer(63)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::LogicalBitFlip(hFFFF_FFFF_FFFF_FFFF, Integer(63)), h7FFF_FFFF_FFFF_FFFF);
}
QUIZ_CASE(poincare_logic_tc_compare)
{
Integer hFFFF = Integer("65535");
Integer hFFFF_FFFF = Integer("4294967295");
Integer hFFFF_0000 = Integer("4294901760");
Integer h1_0000_0000 = Integer("4294967296");
Integer h0000_FFFF_FFFF_0000 = Integer("281474976645120");
Integer hFFFF_FFFF_0000_0000 = Integer("18446744069414584320");
Integer hFFFF_FFFF_FFFF_FFFF = Integer("18446744073709551615");
Integer h7FFF_FFFF_FFFF_FFFF = Integer("9223372036854775807");
Integer hFFFF_0000_0000_FFFF = Integer("18446462598732906495");
assert_equal(Integer::TwosComplementToBits(Integer("-1"), Integer(64)), hFFFF_FFFF_FFFF_FFFF);
assert_equal(Integer::TwosComplementToBits(Integer("-1"), Integer(63)), h7FFF_FFFF_FFFF_FFFF);
assert_equal(Integer::TwosComplementToBits(Integer("-1"), Integer(32)), hFFFF_FFFF);
assert_equal(Integer::TwosComplementToBits(Integer("-1"), Integer(16)), hFFFF);
assert_equal(Integer::TwosComplementToBits(Integer("-4294967296"), Integer(33)), h1_0000_0000);
assert_equal(Integer::TwosComplementToBits(hFFFF_FFFF, Integer(32)), Integer("-1"));
assert_equal(Integer::TwosComplementToBits(hFFFF, Integer(17)), Integer("65535"));
assert_equal(Integer::TwosComplementToBits(hFFFF, Integer(16)), Integer("-1"));
assert_equal(Integer::TwosComplementToBits(h7FFF_FFFF_FFFF_FFFF, Integer(63)), Integer("-1"));
assert_equal(Integer::TwosComplementToBits(hFFFF_FFFF_FFFF_FFFF, Integer(63)), Integer("-1"));
assert_equal(Integer::TwosComplementToBits(hFFFF_FFFF_FFFF_FFFF, Integer(64)), Integer("-1"));
assert_equal(Integer::TwosComplementToBits(hFFFF_FFFF_0000_0000, Integer(64)), Integer("-4294967296"));
assert_equal(Integer::TwosComplementToBits(hFFFF_0000_0000_FFFF, Integer(64)), Integer("-281474976645121"));
assert_equal(Integer::TwosComplementToBits(hFFFF_0000_0000_FFFF, Integer(63)), Integer("-281474976645121"));
assert_equal(Integer::TwosComplementToBits(hFFFF_0000_0000_FFFF, Integer(59)), Integer("-281474976645121"));
assert_equal(Integer::TwosComplementToBits(h1_0000_0000, Integer(33)), Integer("-4294967296"));
assert_equal(Integer::TwosComplementToBits(hFFFF_0000, Integer(33)), Integer("4294901760"));
assert_equal(Integer::TwosComplementToBits(hFFFF_0000, Integer(17)), Integer("-65536"));
}

View File

@@ -423,6 +423,28 @@ QUIZ_CASE(poincare_parsing_identifiers) {
assert_parsed_expression_is("√(1)", SquareRoot::Builder(BasedInteger::Builder(1))); assert_parsed_expression_is("√(1)", SquareRoot::Builder(BasedInteger::Builder(1)));
assert_text_not_parsable("cos(1,2)"); assert_text_not_parsable("cos(1,2)");
assert_text_not_parsable("log(1,2,3)"); assert_text_not_parsable("log(1,2,3)");
assert_parsed_expression_is("and(1,1)", And::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("or(1,1)", Or::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("not(1)", Not::Builder(BasedInteger::Builder(1)));
assert_parsed_expression_is("not(1,1)", NotExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("xor(1,1)", Xor::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bclr(1,1)", BitClear::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bflp(1,1)", BitFlip::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bit(1,1)", BitGet::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bset(1,1)", BitSet::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bic(1,1)", BitsClear::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("bic(1,1,1)", BitsClearExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("rol(1,1)", RotateLeft::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("rol(1,1,1)", RotateLeftExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("ror(1,1)", RotateRight::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("ror(1,1,1)", RotateRightExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("sra(1,1)", ShiftArithmeticRight::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("sra(1,1,1)", ShiftArithmeticRightExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("sll(1,1)", ShiftLogicLeft::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("sll(1,1,1)", ShiftLogicLeftExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("srl(1,1)", ShiftLogicRight::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("srl(1,1,1)", ShiftLogicRightExplicit::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1), BasedInteger::Builder(1)));
assert_parsed_expression_is("tc(1,1)", TwosComplement::Builder(BasedInteger::Builder(1), BasedInteger::Builder(1)));
} }
QUIZ_CASE(poincare_parsing_parse_store) { QUIZ_CASE(poincare_parsing_parse_store) {