mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
- Added clog2 function
- negative numbers can now be displayed in 2's compliment binary
This commit is contained in:
@@ -220,6 +220,14 @@ namespace Poincare
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
};
|
||||
|
||||
class CeilingLog2 final : public Expression {
|
||||
public:
|
||||
CeilingLog2(const BinaryOperationNode<32> *n) : Expression(n) {}
|
||||
static CeilingLog2 Builder(Expression child1) { return TreeHandle::FixedArityBuilder<CeilingLog2, BinaryOperationNode<32> >({child1}); }
|
||||
static constexpr Expression::FunctionHelper s_functionHelper = Expression::FunctionHelper("clog2", 1, &UntypedBuilderOneChild<CeilingLog2>);
|
||||
Expression shallowReduce(ExpressionNode::ReductionContext reductionContext);
|
||||
};
|
||||
|
||||
} // namespace Poincare
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,7 @@ class Expression : public TreeHandle {
|
||||
friend class BitsClearExplicit;
|
||||
friend class BitSet;
|
||||
friend class Ceiling;
|
||||
friend class CeilingLog2;
|
||||
friend class CommonLogarithm;
|
||||
template<typename T>
|
||||
friend class ComplexNode;
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
BinomialCoefficient,
|
||||
BinomPDF,
|
||||
Ceiling,
|
||||
CeilingLog2,
|
||||
ComplexArgument,
|
||||
Conjugate,
|
||||
Derivative,
|
||||
|
||||
@@ -169,6 +169,7 @@ public:
|
||||
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);
|
||||
static Integer CeilingLog2(const Integer &a);
|
||||
|
||||
// Derived expression builder
|
||||
static Expression CreateMixedFraction(const Integer & num, const Integer & denom);
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Poincare {
|
||||
constexpr Expression::FunctionHelper RotateRight::s_functionHelper;
|
||||
constexpr Expression::FunctionHelper RotateRightExplicit::s_functionHelper;
|
||||
constexpr Expression::FunctionHelper TwosComplement::s_functionHelper;
|
||||
constexpr Expression::FunctionHelper CeilingLog2::s_functionHelper;
|
||||
|
||||
template<> int BinaryOperationNode<1>::numberOfChildren() const { return And::s_functionHelper.numberOfChildren(); }
|
||||
template<> int BinaryOperationNode<5>::numberOfChildren() const { return Or::s_functionHelper.numberOfChildren(); }
|
||||
@@ -53,6 +54,7 @@ namespace Poincare {
|
||||
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<> int BinaryOperationNode<32>::numberOfChildren() const { return CeilingLog2::s_functionHelper.numberOfChildren(); }
|
||||
|
||||
template<>
|
||||
Layout BinaryOperationNode<1>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
@@ -164,10 +166,15 @@ namespace Poincare {
|
||||
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, TwosComplement::s_functionHelper.name());
|
||||
}
|
||||
|
||||
template<>
|
||||
Layout BinaryOperationNode<32>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, CeilingLog2::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 == 32 ? CeilingLog2::s_functionHelper.name() :
|
||||
T == 31 ? TwosComplement::s_functionHelper.name() :
|
||||
T == 30 ? RotateRightExplicit::s_functionHelper.name() :
|
||||
T == 29 ? RotateRight::s_functionHelper.name() :
|
||||
@@ -303,6 +310,11 @@ namespace Poincare {
|
||||
return TwosComplement(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
template<>
|
||||
Expression BinaryOperationNode<32>::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
return CeilingLog2(this).shallowReduce(reductionContext);
|
||||
}
|
||||
|
||||
// Check to make sure the the expression is a positive integer
|
||||
Integer getValidInteger(Expression a) {
|
||||
if (a.type() != ExpressionNode::Type::Rational) {
|
||||
@@ -327,11 +339,11 @@ namespace Poincare {
|
||||
Integer cq;
|
||||
Integer x;
|
||||
|
||||
if(aq.isNegative() && t != ExpressionNode::Type::TwosComplement) {
|
||||
if(aq.isNegative() && t != ExpressionNode::Type::TwosComplement && t != ExpressionNode::Type::CeilingLog2) {
|
||||
return Undefined::Builder();
|
||||
}
|
||||
|
||||
if(t != ExpressionNode::Type::Not) {
|
||||
if(t != ExpressionNode::Type::Not && t != ExpressionNode::Type::CeilingLog2) {
|
||||
bq = getValidInteger(e.childAtIndex(1));
|
||||
if(bq.isNegative()) {
|
||||
return Undefined::Builder();
|
||||
@@ -434,6 +446,9 @@ namespace Poincare {
|
||||
case ExpressionNode::Type::TwosComplement:
|
||||
x = Integer::TwosComplementToBits(aq, bq);
|
||||
break;
|
||||
case ExpressionNode::Type::CeilingLog2:
|
||||
x = Integer::CeilingLog2(aq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -530,6 +545,10 @@ namespace Poincare {
|
||||
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::TwosComplement, reductionContext);
|
||||
}
|
||||
|
||||
Expression CeilingLog2::shallowReduce(ExpressionNode::ReductionContext reductionContext) {
|
||||
return BinaryOperation::shallowReduceDirect(*this, ExpressionNode::Type::CeilingLog2, 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;
|
||||
@@ -561,5 +580,6 @@ template int BinaryOperationNode<28>::serialize(char * buffer, int bufferSize, P
|
||||
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;
|
||||
template int BinaryOperationNode<32>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const;
|
||||
|
||||
} // namespace Poincare
|
||||
@@ -272,7 +272,7 @@ bool Expression::isDefinedCosineOrSine(Context * context, Preferences::ComplexFo
|
||||
}
|
||||
|
||||
bool Expression::isBasedIntegerCappedBy(const char * stringInteger) const {
|
||||
return type() == ExpressionNode::Type::BasedInteger && (Integer::NaturalOrder(convert<BasedInteger>().integer(), Integer(stringInteger)) < 0);
|
||||
return type() == ExpressionNode::Type::BasedInteger || (type() == ExpressionNode::Type::Opposite && childAtIndex(0).type() == ExpressionNode::Type::BasedInteger); // && (Integer::NaturalOrder(convert<BasedInteger>().integer(), Integer(stringInteger)) < 0);
|
||||
}
|
||||
|
||||
bool Expression::isDivisionOfIntegers() const {
|
||||
|
||||
@@ -521,7 +521,7 @@ Integer Integer::LogicalShift(const Integer &a, const Integer &shift, const Inte
|
||||
return uint_final;
|
||||
}
|
||||
|
||||
// Sift Left
|
||||
// Shift Left
|
||||
while (points > 0)
|
||||
{
|
||||
uint8_t power = (points >= 31) ? 31 : points;
|
||||
@@ -832,6 +832,29 @@ Integer Integer::TwosComplementToBits(const Integer &a, const Integer &num_bits)
|
||||
return a;
|
||||
}
|
||||
|
||||
Integer Integer::CeilingLog2(const Integer &a)
|
||||
{
|
||||
if (a.isZero())
|
||||
{
|
||||
return Integer(0);
|
||||
}
|
||||
uint8_t bits = 0;
|
||||
Integer buffer;
|
||||
if(a.isNegative()) {
|
||||
Integer x2 = Integer::Multiplication(a,2);
|
||||
x2.setNegative(false);
|
||||
buffer = Integer::Subtraction(x2, Integer(1));
|
||||
} else {
|
||||
buffer = a;
|
||||
}
|
||||
while(!buffer.isZero()) {
|
||||
bits++;
|
||||
buffer = Integer::LogicalShift(buffer,Integer(-1));
|
||||
}
|
||||
Integer num_bits_in_a = Integer(bits);
|
||||
return num_bits_in_a;
|
||||
}
|
||||
|
||||
Integer Integer::addition(const Integer & a, const Integer & b, bool inverseBNegative, bool oneDigitOverflow) {
|
||||
bool bNegative = (inverseBNegative ? !b.m_negative : b.m_negative);
|
||||
if (a.m_negative == bNegative) {
|
||||
|
||||
@@ -114,6 +114,7 @@ private:
|
||||
&BitGet::s_functionHelper,
|
||||
&BitSet::s_functionHelper,
|
||||
&Ceiling::s_functionHelper,
|
||||
&CeilingLog2::s_functionHelper,
|
||||
&ConfidenceInterval::s_functionHelper,
|
||||
&Conjugate::s_functionHelper,
|
||||
&Cosine::s_functionHelper,
|
||||
|
||||
@@ -295,6 +295,7 @@ template BinomialCoefficient TreeHandle::FixedArityBuilder<BinomialCoefficient,
|
||||
template BinomialCoefficientLayout TreeHandle::FixedArityBuilder<BinomialCoefficientLayout, BinomialCoefficientLayoutNode>(const Tuple &);
|
||||
template BinomPDF TreeHandle::FixedArityBuilder<BinomPDF, BinomPDFNode>(const Tuple &);
|
||||
template Ceiling TreeHandle::FixedArityBuilder<Ceiling, CeilingNode>(const Tuple &);
|
||||
template CeilingLog2 TreeHandle::FixedArityBuilder<CeilingLog2, BinaryOperationNode<32> >(const Tuple &);
|
||||
template CeilingLayout TreeHandle::FixedArityBuilder<CeilingLayout, CeilingLayoutNode>(const Tuple &);
|
||||
template CommonLogarithm TreeHandle::FixedArityBuilder<CommonLogarithm, LogarithmNode<1> >(const Tuple &);
|
||||
template ComplexArgument TreeHandle::FixedArityBuilder<ComplexArgument, ComplexArgumentNode>(const Tuple &);
|
||||
|
||||
Reference in New Issue
Block a user