mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] FracPart
This commit is contained in:
@@ -64,6 +64,7 @@ objs += $(addprefix poincare/src/,\
|
||||
factorial.o\
|
||||
float.o\
|
||||
floor.o\
|
||||
frac_part.o\
|
||||
ghost_node.o\
|
||||
global_context.o\
|
||||
hyperbolic_arc_cosine.o\
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
#include <poincare/equal.h>
|
||||
#include <poincare/factorial.h>
|
||||
#include <poincare/floor.h>
|
||||
#include <poincare/frac_part.h>
|
||||
#include <poincare/sine.h>
|
||||
#include <poincare/tangent.h>
|
||||
#include <poincare/hyperbolic_arc_cosine.h>
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
#ifndef POINCARE_FRAC_PART_H
|
||||
#define POINCARE_FRAC_PART_H
|
||||
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/approximation_helper.h>
|
||||
#include <poincare/expression.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class FracPart : public StaticHierarchy<1> {
|
||||
using StaticHierarchy<1>::StaticHierarchy;
|
||||
class FracPartNode : public ExpressionNode {
|
||||
public:
|
||||
Type type() const override;
|
||||
// Allocation Failure
|
||||
static FracPartNode * FailedAllocationStaticNode();
|
||||
FracPartNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(FracPartNode); }
|
||||
int numberOfChildren() const override { return 1; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "FracPart";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::FracPart; }
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
// Layout
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
const char * name() const { return "frac"; }
|
||||
/* Simplification */
|
||||
// Simplification
|
||||
Expression shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const override;
|
||||
/* Evaluation */
|
||||
template<typename T> static std::complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
// Evaluation
|
||||
template<typename T> static Complex<T> computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit);
|
||||
Evaluation<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return ApproximationHelper::Map<float>(this, context, angleUnit, computeOnComplex<float>);
|
||||
}
|
||||
@@ -32,6 +40,17 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class FracPart : public Expression {
|
||||
public:
|
||||
FracPart() : Expression(TreePool::sharedPool()->createTreeNode<FracPartNode>()) {}
|
||||
FracPart(const FracPartNode * n) : Expression(n) {}
|
||||
FracPart(Expression operand) : FracPart() {
|
||||
replaceChildAtIndexInPlace(0, operand);
|
||||
}
|
||||
|
||||
Expression shallowReduce(Context & context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -133,8 +133,8 @@ cosh { poincare_expression_yylval.expression = HyperbolicCosine(); return FUNCTI
|
||||
/*factor { poincare_expression_yylval.expression = new Factor(); return FUNCTION; }
|
||||
*/
|
||||
floor { poincare_expression_yylval.expression = Floor(); return FUNCTION; }
|
||||
/*frac { poincare_expression_yylval.expression = new FracPart(); return FUNCTION; }
|
||||
gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; }
|
||||
frac { poincare_expression_yylval.expression = FracPart(); return FUNCTION; }
|
||||
/*gcd { poincare_expression_yylval.expression = new GreatCommonDivisor(); return FUNCTION; }
|
||||
im { poincare_expression_yylval.expression = new ImaginaryPart(); return FUNCTION; }
|
||||
int { poincare_expression_yylval.expression = new Integral(); return FUNCTION; }
|
||||
inverse { poincare_expression_yylval.expression = new MatrixInverse(); return FUNCTION; }
|
||||
|
||||
@@ -16,7 +16,6 @@ FloorNode * FloorNode::FailedAllocationStaticNode() {
|
||||
return &failure;
|
||||
}
|
||||
|
||||
|
||||
LayoutRef FloorNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return FloorLayoutRef(childAtIndex(0)->createLayout(floatDisplayMode, numberOfSignificantDigits));
|
||||
}
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
#include <poincare/frac_part.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
#include <poincare/simplification_helper.h>
|
||||
#include <poincare/rational.h>
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
}
|
||||
#include <cmath>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
ExpressionNode::Type FracPart::type() const {
|
||||
return Type::FracPart;
|
||||
FracPartNode * FracPartNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureExpressionNode<FracPartNode> failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
Expression * FracPart::clone() const {
|
||||
FracPart * c = new FracPart(m_operands, true);
|
||||
return c;
|
||||
LayoutRef FracPartNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(FracPart(this), floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
|
||||
int FracPartNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
|
||||
Expression FracPartNode::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
return FracPart(this).shallowReduce(context, angleUnit);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Complex<T> FracPartNode::computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit) {
|
||||
if (c.imag() != 0) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
return Complex<T>(c.real()-std::floor(c.real()));
|
||||
}
|
||||
|
||||
Expression FracPart::shallowReduce(Context& context, Preferences::AngleUnit angleUnit) const {
|
||||
@@ -22,26 +38,18 @@ Expression FracPart::shallowReduce(Context& context, Preferences::AngleUnit angl
|
||||
if (e.isUndefinedOrAllocationFailure()) {
|
||||
return e;
|
||||
}
|
||||
Expression * op = childAtIndex(0);
|
||||
Expression c = childAtIndex(0);
|
||||
#if MATRIX_EXACT_REDUCING
|
||||
if (op->type() == Type::Matrix) {
|
||||
return SimplificationHelper::Map(this, context, angleUnit);
|
||||
if (c.type() == ExpressionNode::Type::Matrix) {
|
||||
return SimplificationHelper::Map(*this, context, angleUnit);
|
||||
}
|
||||
#endif
|
||||
if (op->type() != Type::Rational) {
|
||||
return this;
|
||||
if (c.type() != ExpressionNode::Type::Rational) {
|
||||
return *this;
|
||||
}
|
||||
Rational * r = static_cast<Rational *>(op);
|
||||
IntegerDivision div = Integer::Division(r->numerator(), r->denominator());
|
||||
return replaceWith(new Rational(div.remainder, r->denominator()), true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::complex<T> FracPart::computeOnComplex(const std::complex<T> c, Preferences::AngleUnit angleUnit) {
|
||||
if (c.imag() != 0) {
|
||||
return Complex<T>::Undefined();
|
||||
}
|
||||
return Complex<T>(c.real()-std::floor(c.real()));
|
||||
Rational r = static_cast<Rational>(c);
|
||||
IntegerDivision div = Integer::Division(r.signedIntegerNumerator(), r.integerDenominator());
|
||||
return Rational(div.remainder, r.integerDenominator());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ QUIZ_CASE(poincare_parse_function) {
|
||||
assert_parsed_expression_type("factor(23/42)", ExpressionNode::Type::Factor);
|
||||
#endif
|
||||
assert_parsed_expression_type("floor(2.3)", ExpressionNode::Type::Floor);
|
||||
#if 0
|
||||
assert_parsed_expression_type("frac(2.3)", ExpressionNode::Type::FracPart);
|
||||
#if 0
|
||||
assert_parsed_expression_type("gcd(2,3)", ExpressionNode::Type::GreatCommonDivisor);
|
||||
assert_parsed_expression_type("im(2+I)", ExpressionNode::Type::ImaginaryPart);
|
||||
assert_parsed_expression_type("int(x, 2, 3)", ExpressionNode::Type::Integral);
|
||||
@@ -103,9 +103,9 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
assert_parsed_expression_evaluates_to<float>("floor(2.3)", "2");
|
||||
assert_parsed_expression_evaluates_to<double>("floor(2.3)", "2");
|
||||
|
||||
#if 0
|
||||
assert_parsed_expression_evaluates_to<float>("frac(2.3)", "0.3");
|
||||
assert_parsed_expression_evaluates_to<double>("frac(2.3)", "0.3");
|
||||
#if 0
|
||||
|
||||
assert_parsed_expression_evaluates_to<float>("gcd(234,394)", "2");
|
||||
assert_parsed_expression_evaluates_to<double>("gcd(234,394)", "2");
|
||||
@@ -272,8 +272,8 @@ QUIZ_CASE(poincare_function_simplify) {
|
||||
assert_parsed_expression_simplify_to("factor(10007^2)", "undef");
|
||||
#endif
|
||||
assert_parsed_expression_simplify_to("floor(-1.3)", "-2");
|
||||
#if 0
|
||||
assert_parsed_expression_simplify_to("frac(-1.3)", "7/10");
|
||||
#if 0
|
||||
assert_parsed_expression_simplify_to("gcd(123,278)", "1");
|
||||
assert_parsed_expression_simplify_to("gcd(11,121)", "11");
|
||||
assert_parsed_expression_simplify_to("lcm(123,278)", "34194");
|
||||
|
||||
Reference in New Issue
Block a user