mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-24 08:10:50 +01:00
[poincare] Fix Randint
This commit is contained in:
@@ -100,6 +100,7 @@ objs += $(addprefix poincare/src/,\
|
||||
print_float.o\
|
||||
preferences.o\
|
||||
product.o\
|
||||
randint.o\
|
||||
random.o\
|
||||
rational.o\
|
||||
real_part.o\
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
#include <poincare/matrix_complex.h>
|
||||
#include <poincare/multiplication.h>
|
||||
#include <poincare/power.h>
|
||||
#include <poincare/randint.h>
|
||||
#include <poincare/random.h>
|
||||
#include <poincare/subtraction.h>
|
||||
#include <poincare/undefined.h>
|
||||
|
||||
@@ -1,32 +1,54 @@
|
||||
#ifndef POINCARE_RANDINT_H
|
||||
#define POINCARE_RANDINT_H
|
||||
|
||||
#include <poincare/static_hierarchy.h>
|
||||
#include <poincare/layout_helper.h>
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/serialization_helper.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class Randint : public StaticHierarchy<2> {
|
||||
using StaticHierarchy<2>::StaticHierarchy;
|
||||
class RandintNode : public ExpressionNode {
|
||||
public:
|
||||
Type type() const override;
|
||||
private:
|
||||
/* Layout */
|
||||
LayoutRef createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return LayoutHelper::Prefix(this, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
// Allocation Failure
|
||||
static RandintNode * FailedAllocationStaticNode();
|
||||
RandintNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(RandintNode); }
|
||||
int numberOfChildren() const override { return 2; }
|
||||
#if POINCARE_TREE_LOG
|
||||
virtual void logNodeName(std::ostream & stream) const override {
|
||||
stream << "Randint";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Properties
|
||||
Type type() const override { return Type::Randint; }
|
||||
private:
|
||||
// Layout
|
||||
LayoutReference createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override;
|
||||
int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override {
|
||||
return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
const char * name() const { return "randint"; }
|
||||
/* Evaluation */
|
||||
// Evaluation
|
||||
Evaluation<float> approximate(SinglePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<float>(context, angleUnit);
|
||||
}
|
||||
Evaluation<double> approximate(DoublePrecision p, Context& context, Preferences::AngleUnit angleUnit) const override {
|
||||
return templateApproximate<double>(context, angleUnit);
|
||||
}
|
||||
template <typename T> Evaluation<T> templateApproximate()Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
template <typename T> Evaluation<T> templateApproximate(Context& context, Preferences::AngleUnit angleUnit) const;
|
||||
};
|
||||
|
||||
class Randint : public Expression {
|
||||
friend class RandintNode;
|
||||
public:
|
||||
Randint() : Expression(TreePool::sharedPool()->createTreeNode<RandintNode>()) {}
|
||||
Randint(const RandintNode * n) : Expression(n) {}
|
||||
|
||||
template<typename T> static T random();
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -146,8 +146,7 @@ prediction { poincare_expression_yylval.expression = SimplePredictionInterval();
|
||||
product { poincare_expression_yylval.expression = Product(); return FUNCTION; }
|
||||
quo { poincare_expression_yylval.expression = DivisionQuotient(); return FUNCTION; }
|
||||
random { poincare_expression_yylval.expression = Random(); return FUNCTION; }
|
||||
/*randint { poincare_expression_yylval.expression = new Randint(); return FUNCTION; }
|
||||
*/
|
||||
randint { poincare_expression_yylval.expression = Randint(); return FUNCTION; }
|
||||
re { poincare_expression_yylval.expression = RealPart(); return FUNCTION; }
|
||||
rem { poincare_expression_yylval.expression = DivisionRemainder(); return FUNCTION; }
|
||||
root { poincare_expression_yylval.expression = NthRoot(); return FUNCTION; }
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <poincare/randint.h>
|
||||
#include <poincare/random.h>
|
||||
#include <poincare/allocation_failure_expression_node.h>
|
||||
#include <ion.h>
|
||||
|
||||
extern "C" {
|
||||
@@ -9,28 +10,27 @@ extern "C" {
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
ExpressionNode::Type Randint::type() const {
|
||||
return Type::Randint;
|
||||
RandintNode * RandintNode::FailedAllocationStaticNode() {
|
||||
static AllocationFailureExpressionNode<RandintNode> failure;
|
||||
TreePool::sharedPool()->registerStaticNodeIfRequired(&failure);
|
||||
return &failure;
|
||||
}
|
||||
|
||||
Expression * Randint::clone() const {
|
||||
Randint * a = new Randint(m_operands, true);
|
||||
return a;
|
||||
LayoutReference RandintNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||
return LayoutHelper::Prefix(Randint(this), floatDisplayMode, numberOfSignificantDigits, name());
|
||||
}
|
||||
|
||||
template <typename T> Evaluation<T> * Randint::templateApproximate(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> * aInput = childAtIndex(0)->approximate(T(), context, angleUnit);
|
||||
Evaluation<T> * bInput = childAtIndex(1)->approximate(T(), context, angleUnit);
|
||||
T a = aInput->toScalar();
|
||||
T b = bInput->toScalar();
|
||||
delete aInput;
|
||||
delete bInput;
|
||||
template <typename T> Evaluation<T> RandintNode::templateApproximate(Context & context, Preferences::AngleUnit angleUnit) const {
|
||||
Evaluation<T> aInput = childAtIndex(0)->approximate(T(), context, angleUnit);
|
||||
Evaluation<T> bInput = childAtIndex(1)->approximate(T(), context, angleUnit);
|
||||
T a = aInput.toScalar();
|
||||
T b = bInput.toScalar();
|
||||
if (std::isnan(a) || std::isnan(b) || a != std::round(a) || b != std::round(b) || a > b) {
|
||||
return new Complex<T>(Complex<T>::Undefined());
|
||||
return Complex<T>::Undefined();
|
||||
|
||||
}
|
||||
T result = std::floor(Random::random<T>()*(b+1.0-a)+a);
|
||||
return new Complex<T>(result);
|
||||
return Complex<T>(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,9 +50,7 @@ QUIZ_CASE(poincare_parse_function) {
|
||||
assert_parsed_expression_type("quo(29, 10)", ExpressionNode::Type::DivisionQuotient);
|
||||
|
||||
assert_parsed_expression_type("random()", ExpressionNode::Type::Random);
|
||||
#if 0
|
||||
assert_parsed_expression_type("randint(1, 2)", ExpressionNode::Type::Randint);
|
||||
#endif
|
||||
|
||||
assert_parsed_expression_type("re(2+I)", ExpressionNode::Type::RealPart);
|
||||
assert_parsed_expression_type("rem(29, 10)", ExpressionNode::Type::DivisionRemainder);
|
||||
@@ -230,12 +228,9 @@ QUIZ_CASE(poincare_function_evaluate) {
|
||||
assert_exp_is_bounded(exp, 0.0f, 1.0f);
|
||||
assert_exp_is_bounded(exp, 0.0, 1.0);
|
||||
|
||||
#if 0
|
||||
exp = parse_expression("randint(4,45)");
|
||||
assert_exp_is_bounded(exp, 4.0f, 45.0f, true);
|
||||
assert_exp_is_bounded(exp, 4.0, 45.0, true);
|
||||
delete exp;
|
||||
#endif
|
||||
}
|
||||
|
||||
QUIZ_CASE(poincare_function_simplify) {
|
||||
|
||||
Reference in New Issue
Block a user