[poincare] Expand numbers to complex numbers

Change-Id: I2e7cf5240e184da45b656ee4f121ad76aabfd1c7
This commit is contained in:
Émilie Feral
2017-02-02 17:37:01 +01:00
parent 131b364ae9
commit 676bd46f33
66 changed files with 602 additions and 392 deletions

View File

@@ -78,11 +78,11 @@ float CurveView::floatToPixel(Axis axis, float f) const {
}
void CurveView::computeLabels(Axis axis) {
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
float step = gridUnit(axis);
for (int index = 0; index < numberOfLabels(axis); index++) {
Float(2.0f*step*(ceilf(min(axis)/(2.0f*step)))+index*2.0f*step).convertFloatToText(buffer,
Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits),
Complex::convertFloatToText(2.0f*step*(ceilf(min(axis)/(2.0f*step)))+index*2.0f*step, buffer,
Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits),
Constant::ShortNumberOfSignificantDigits, Expression::DisplayMode::Auto);
//TODO: check for size of label?
strlcpy(label(axis, index), buffer, strlen(buffer)+1);

View File

@@ -69,7 +69,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(T
// The cell is editable
if (cellAtLocationIsEditable(i, j)) {
EvenOddEditableTextCell * myEditableValueCell = (EvenOddEditableTextCell *)cell;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
// Special case 1: last row
if (j == numberOfRows() - 1) {
/* Display an empty line only if there is enough space for a new element in
@@ -80,7 +80,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(T
return;
}
}
Float(dataAtLocation(i, j)).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, displayMode);
Complex::convertFloatToText(dataAtLocation(i, j), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, displayMode);
myEditableValueCell->setText(buffer);
return;
}

View File

@@ -26,8 +26,8 @@ int FloatParameterController::activeCell() {
void FloatParameterController::willDisplayCellForIndex(TableViewCell * cell, int index) {
EditableTextMenuListCell * myCell = (EditableTextMenuListCell *) cell;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Float(parameterAtIndex(index)).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Expression::DisplayMode::Auto);
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Complex::convertFloatToText(parameterAtIndex(index), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, Expression::DisplayMode::Auto);
myCell->setAccessoryText(buffer);
}

View File

@@ -77,13 +77,13 @@ void Function::setDisplayDerivative(bool display) {
float Function::evaluateAtAbscissa(float x, Context * context, Expression::AngleUnit angleUnit) const {
Symbol xSymbol = Symbol('x');
Float e = Float(x);
Complex e = Complex(x);
context->setExpressionForSymbolName(&e, &xSymbol);
return m_expression->approximate(*context, angleUnit);
}
float Function::approximateDerivative(float x, Context * context, Expression::AngleUnit angleUnit) const {
Float abscissa = Float(x);
Complex abscissa = Complex(x);
Expression * args[2] = {m_expression, &abscissa};
Derivative derivative = Derivative();
derivative.setArgument(args, 2, true);

View File

@@ -112,11 +112,11 @@ bool GraphController::handleEnter() {
void GraphController::reloadBannerView() {
App * myApp = (App *)app();
AppsContainer * myContainer = (AppsContainer *)myApp->container();
char buffer[k_maxNumberOfCharacters+Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[k_maxNumberOfCharacters+Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
const char * legend = "x = ";
int legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
Float(m_cursor.x()).convertFloatToText(buffer+ legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
Complex::convertFloatToText(m_cursor.x(), buffer+ legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 0);
legend = "00(x) = ";
@@ -124,7 +124,7 @@ void GraphController::reloadBannerView() {
strlcpy(buffer, legend, legendLength+1);
Function * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor);
buffer[1] = f->name()[0];
Float(m_cursor.y()).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
Complex::convertFloatToText(m_cursor.y(), buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer+1, 1);
if (m_bannerView.displayDerivative()) {
@@ -132,7 +132,7 @@ void GraphController::reloadBannerView() {
buffer[1] = '\'';
App * graphApp = (Graph::App *)app();
float y = f->approximateDerivative(m_cursor.x(), graphApp->localContext(), myContainer->preferences()->angleUnit());
Float(y).convertFloatToText(buffer + legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
Complex::convertFloatToText(y, buffer + legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 2);
}
}

View File

@@ -21,8 +21,8 @@ public:
private:
char * label(Axis axis, int index) const override;
float evaluateModelWithParameter(Model * expression, float abscissa) const override;
char m_xLabels[k_maxNumberOfXLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_yLabels[k_maxNumberOfYLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_xLabels[k_maxNumberOfXLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_yLabels[k_maxNumberOfYLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
FunctionStore * m_functionStore;
Context * m_context;
Preferences * m_preferences;

View File

@@ -167,7 +167,7 @@ void ValuesController::willDisplayCellAtLocation(TableViewCell * cell, int i, in
return;
}
// The cell is not a title cell
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
// Special case: last row
if (j == numberOfRows() - 1) {
int numberOfIntervalElements = m_interval.numberOfElements();
@@ -184,9 +184,9 @@ void ValuesController::willDisplayCellAtLocation(TableViewCell * cell, int i, in
App * graphApp = (Graph::App *)app();
float x = m_interval.element(j-1);
if (isDerivativeColumn(i)) {
Float(function->approximateDerivative(x, graphApp->localContext(), myContainer->preferences()->angleUnit())).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
Complex::convertFloatToText(function->approximateDerivative(x, graphApp->localContext(), myContainer->preferences()->angleUnit()), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
} else {
Float(function->evaluateAtAbscissa(x, graphApp->localContext(), myContainer->preferences()->angleUnit())).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
Complex::convertFloatToText(function->evaluateAtAbscissa(x, graphApp->localContext(), myContainer->preferences()->angleUnit()), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, myContainer->preferences()->displayMode());
}
myValueCell->setText(buffer);
}

View File

@@ -66,8 +66,8 @@ View * CalculationController::ContentView::subviewAtIndex(int index) {
}
void CalculationController::ContentView::willDisplayEditableCellAtIndex(int index) {
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
Float(m_calculation->parameterAtIndex(index)).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Expression::DisplayMode::Auto);
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
Complex::convertFloatToText(m_calculation->parameterAtIndex(index), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Expression::DisplayMode::Auto);
m_calculationCell[index].setText(buffer);
}
@@ -240,8 +240,8 @@ void CalculationController::updateTitle() {
m_titleBuffer[currentChar++] = m_law->parameterNameAtIndex(index)[0];
strlcpy(m_titleBuffer+currentChar, " = ", 4);
currentChar += 3;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
Float(m_law->parameterValueAtIndex(index)).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Expression::DisplayMode::Auto);
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
Complex::convertFloatToText(m_law->parameterValueAtIndex(index), buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Expression::DisplayMode::Auto);
strlcpy(m_titleBuffer+currentChar, buffer, strlen(buffer)+1);
currentChar += strlen(buffer);
m_titleBuffer[currentChar++] = ' ';

View File

@@ -19,7 +19,7 @@ public:
protected:
char * label(Axis axis, int index) const override;
private:
char m_labels[k_maxNumberOfXLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_labels[k_maxNumberOfXLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
float evaluateModelWithParameter(Model * law, float abscissa) const override;
Law * m_law;
Calculation * m_calculation;

View File

@@ -132,10 +132,10 @@ void CalculationController::willDisplayCellAtLocation(TableViewCell * cell, int
float calculation1 = (m_store->*calculationMethods[j-1])(0);
float calculation2 = (m_store->*calculationMethods[j-1])(1);
EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Float(calculation1).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Complex::convertFloatToText(calculation1, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
myCell->setFirstText(buffer);
Float(calculation2).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(calculation2, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
myCell->setSecondText(buffer);
return;
}
@@ -144,8 +144,8 @@ void CalculationController::willDisplayCellAtLocation(TableViewCell * cell, int
&Store::columnProductSum, &Store::correlationCoefficient, &Store::squaredCorrelationCoefficient};
float calculation = (m_store->*calculationMethods[j-6])();
EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)cell;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Float(calculation).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
Complex::convertFloatToText(calculation, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
myCell->setText(buffer);
return;
}

View File

@@ -56,19 +56,19 @@ bool GraphController::handleEnter() {
void GraphController::reloadBannerView() {
AppsContainer * container = (AppsContainer *)app()->container();
m_bannerView.setLegendAtIndex((char *)"y = ax+b", 0);
char buffer[k_maxNumberOfCharacters + Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[k_maxNumberOfCharacters + Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
const char * legend = "a = ";
float slope = m_store->slope();
int legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
Float(slope).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(slope, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 1);
legend = "b = ";
float yIntercept = m_store->yIntercept();
legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
Float(yIntercept).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(yIntercept, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 2);
legend = "x = ";
@@ -81,7 +81,7 @@ void GraphController::reloadBannerView() {
}
legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
Float(x).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(x, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 3);
legend = "y = ";
@@ -93,7 +93,7 @@ void GraphController::reloadBannerView() {
}
legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
Float(y).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(y, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 4);
}

View File

@@ -16,8 +16,8 @@ private:
char * label(Axis axis, int index) const override;
float evaluateModelWithParameter(Model * curve, float t) const override;
Store * m_store;
char m_xLabels[k_maxNumberOfXLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_yLabels[k_maxNumberOfYLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_xLabels[k_maxNumberOfXLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_yLabels[k_maxNumberOfYLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
};
}

View File

@@ -73,12 +73,12 @@ Responder * BoxController::tabController() const {
void BoxController::reloadBannerView() {
const char * calculationName[5] = {"Minimum", "Premier quartile", "Mediane", "Troisieme quartile", "Maximum"};
m_boxBannerView.setLegendAtIndex((char *)calculationName[(int)m_view.selectedQuantile()], 0);
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
CalculPointer calculationMethods[5] = {&Store::minValue, &Store::firstQuartile, &Store::median, &Store::thirdQuartile,
&Store::maxValue};
float calculation = (m_store->*calculationMethods[(int)m_view.selectedQuantile()])();
AppsContainer * container = (AppsContainer *)app()->container();
Float(calculation).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(calculation, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_boxBannerView.setLegendAtIndex(buffer, 1);
}

View File

@@ -28,7 +28,7 @@ private:
char * label(Axis axis, int index) const override;
Store * m_store;
BoxRange m_boxRange;
char m_labels[k_maxNumberOfXLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_labels[k_maxNumberOfXLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
Quantile m_selectedQuantile;
};

View File

@@ -87,9 +87,9 @@ void CalculationController::willDisplayCellAtLocation(TableViewCell * cell, int
&Store::thirdQuartile, &Store::median, &Store::quartileRange, &Store::sum, &Store::squaredValueSum};
float calculation = (m_store->*calculationMethods[j])();
EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)cell;
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
AppsContainer * container = (AppsContainer *)app()->container();
Float(calculation).convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(calculation, buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
myCell->setText(buffer);
}
}

View File

@@ -133,15 +133,15 @@ Responder * HistogramController::tabController() const {
void HistogramController::reloadBannerView() {
AppsContainer * container = (AppsContainer *)app()->container();
char buffer[k_maxNumberOfCharacters+ Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)*2];
char buffer[k_maxNumberOfCharacters+ Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)*2];
const char * legend = "Interval [";
int legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
float lowerBound = m_store->startOfBarAtIndex(m_selectedBarIndex);
int lowerBoundNumberOfChar = Float(lowerBound).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
int lowerBoundNumberOfChar = Complex::convertFloatToText(lowerBound, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
buffer[legendLength+lowerBoundNumberOfChar] = ';';
float upperBound = m_store->endOfBarAtIndex(m_selectedBarIndex);
int upperBoundNumberOfChar = Float(upperBound).convertFloatToText(buffer+legendLength+lowerBoundNumberOfChar+1, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
int upperBoundNumberOfChar = Complex::convertFloatToText(upperBound, buffer+legendLength+lowerBoundNumberOfChar+1, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
buffer[legendLength+lowerBoundNumberOfChar+upperBoundNumberOfChar+1] = '[';
buffer[legendLength+lowerBoundNumberOfChar+upperBoundNumberOfChar+2] = 0;
m_bannerView.setLegendAtIndex(buffer, 0);
@@ -150,14 +150,14 @@ void HistogramController::reloadBannerView() {
legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
float size = m_store->heightOfBarAtIndex(m_selectedBarIndex);
Float(size).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(size, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 1);
legend = "Frequence: ";
legendLength = strlen(legend);
strlcpy(buffer, legend, legendLength+1);
float frequency = size/m_store->sumOfColumn(1);
Float(frequency).convertFloatToText(buffer+legendLength, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
Complex::convertFloatToText(frequency, buffer+legendLength, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits, container->preferences()->displayMode());
m_bannerView.setLegendAtIndex(buffer, 2);
}

View File

@@ -18,7 +18,7 @@ private:
char * label(Axis axis, int index) const override;
float evaluateModelWithParameter(Model * curve, float t) const override;
Store * m_store;
char m_labels[k_maxNumberOfXLabels][Float::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
char m_labels[k_maxNumberOfXLabels][Complex::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
float m_highlightedBarStart;
float m_highlightedBarEnd;
};

View File

@@ -112,8 +112,8 @@ void VariableBoxController::ContentViewController::willDisplayCellForIndex(Table
const Expression * expression = expressionForIndex(index);
if (m_currentPage == Page::Scalar) {
myCell->displayExpression(false);
char buffer[Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
((Float *)expression)->convertFloatToText(buffer, Float::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
char buffer[Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
((Complex *)expression)->writeTextInBuffer(buffer, Complex::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits));
myCell->setSubtitle(buffer);
return;
}

View File

@@ -7,11 +7,11 @@ objs += $(addprefix poincare/src/,\
addition.o\
binary_operation.o\
cosine.o\
complex.o\
derivative.o\
expression.o\
expression_lexer.o\
expression_parser.o\
float.o\
fraction.o\
function.o\
global_context.o\
@@ -55,7 +55,7 @@ objs += $(addprefix poincare/src/layout/,\
tests += $(addprefix poincare/test/,\
addition.cpp\
float.cpp\
complex.cpp\
fraction.cpp\
identity.cpp\
integer.cpp\

View File

@@ -3,11 +3,11 @@
#include <poincare/absolute_value.h>
#include <poincare/addition.h>
#include <poincare/complex.h>
#include <poincare/context.h>
#include <poincare/cosine.h>
#include <poincare/derivative.h>
#include <poincare/expression.h>
#include <poincare/float.h>
#include <poincare/fraction.h>
#include <poincare/function.h>
#include <poincare/global_context.h>

View File

@@ -7,6 +7,7 @@ class AbsoluteValue : public Function {
public:
AbsoluteValue();
float approximate(Context & context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;

View File

@@ -2,22 +2,18 @@
#define POINCARE_ADDITION_H
#include <poincare/binary_operation.h>
#include <poincare/float.h>
#include <poincare/matrix.h>
class Addition : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
Type type() const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
bool isCommutative() const override;
private:
Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
public:
Type type() const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
bool isCommutative() const override;
private:
Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const override;
};
#endif

View File

@@ -3,21 +3,22 @@
#include <poincare/expression.h>
#include <poincare/matrix.h>
#include <poincare/float.h>
#include <poincare/complex.h>
class BinaryOperation : public Expression {
public:
BinaryOperation(Expression ** operands, bool cloneOperands = true);
~BinaryOperation();
const Expression * operand(int i) const override;
int numberOfOperands() const override;
Expression * clone() const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
protected:
Expression * m_operands[2];
virtual Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const;
virtual Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const;
virtual Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const;
public:
BinaryOperation(Expression ** operands, bool cloneOperands = true);
~BinaryOperation();
const Expression * operand(int i) const override;
int numberOfOperands() const override;
Expression * clone() const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
protected:
Expression * m_operands[2];
virtual Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const = 0;
virtual Expression * evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const;
virtual Expression * evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const;
virtual Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const;
};
#endif

View File

@@ -1,36 +1,36 @@
#ifndef POINCARE_FLOAT_H
#define POINCARE_FLOAT_H
#ifndef POINCARE_COMPLEX_H
#define POINCARE_COMPLEX_H
#include <poincare/leaf_expression.h>
class Float : public LeafExpression {
class Complex : public LeafExpression {
public:
Float(float f);
Float(const char * integralPart, int integralPartLength, bool integralNegative,
Complex(float a, float b = 0.0f);
Complex(const char * integralPart, int integralPartLength, bool integralNegative,
const char * fractionalPart, int fractionalPartLength,
const char * exponent, int exponentLength, bool exponentNegative);
void setNumberOfSignificantDigits(int numberOfDigits);
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * clone() const override;
bool valueEquals(const Expression * e) const override;
void setNumberOfSignificantDigits(int numberOfDigits);
int writeTextInBuffer(char * buffer, int bufferSize) override;
float a();
float b();
float absoluteValue();
/* The parameter 'DisplayMode' refers to the way to display float 'scientific'
* or 'auto'. The scientific mode returns float with style -1.2E2 whereas
* the auto mode tries to return 'natural' float like (0.021) and switches
* to scientific mode if the float is too small or too big regarding the
* number of significant difits. If the buffer size is too small to display
* number of significant digits. If the buffer size is too small to display
* the right number of significant digits, the function forces the scientific
* mode and cap the number of significant digits to fit the buffer. If the
* buffer is too small to display any float, the text representing the float
* is truncated at the end of the buffer.
* ConvertFloat to Text return the number of characters that have been written
* in buffer (excluding the last \O character) */
int convertFloatToText(char * buffer, int bufferSize, int numberOfSignificantDigits, DisplayMode mode = DisplayMode::Scientific) const;
int writeTextInBuffer(char * buffer, int bufferSize) override;
static int convertFloatToText(float f, char * buffer, int bufferSize, int numberOfSignificantDigits, DisplayMode mode = DisplayMode::Scientific);
constexpr static int bufferSizeForFloatsWithPrecision(int numberOfSignificantDigits) {
// The wors case is -1.234E-38
return numberOfSignificantDigits + 7;
@@ -40,9 +40,14 @@ private:
* At maximum, the number has 7 significant digits so, in the worst case it
* has the form -1.999999e-38 (7+6+1 char) (the auto mode is always
* shorter. */
constexpr static int k_maxBufferLength = 7+6+1;
/* convertFloatToTextPrivate return the string length of the buffer (does not count the 0 last char)*/
int convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigits, DisplayMode mode) const;
constexpr static int k_maxFloatBufferLength = 7+6+1;
/* We here define the buffer size to write the lengthest complex possible.
* The worst case has the form -1.999999E-38-1.999999E-38 (13+13+1 char) */
constexpr static int k_maxComplexBufferLength = 13+13+1;
/* convertComplexToText and convertFloatToTextPrivate return the string length
* of the buffer (does not count the 0 last char)*/
int convertComplexToText(char * buffer, int bufferSize, DisplayMode displayMode) const;
static int convertFloatToTextPrivate(float f, char * buffer, int numberOfSignificantDigits, DisplayMode mode);
/* This function prints the int i in the buffer with a '.' at the position
* specified by the decimalMarkerPosition. It starts printing at the end of the
* buffer and print from right to left. The integer given should be of the right
@@ -51,9 +56,9 @@ private:
* big, the printing stops when no more empty chars are available without
* returning any warning. */
static void printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, int i, int decimalMarkerPosition);
float m_float;
float m_a;
float m_b;
int m_numberOfSignificantDigits;
};
#endif

View File

@@ -11,6 +11,7 @@ class Expression {
enum class Type : uint8_t {
AbsoluteValue,
Addition,
Complex,
Cosine,
Derivative,
Float,

View File

@@ -2,8 +2,6 @@
#define POINCARE_FRACTION_H
#include <poincare/binary_operation.h>
#include <poincare/float.h>
#include <poincare/matrix.h>
class Fraction : public BinaryOperation {
using BinaryOperation::BinaryOperation;
@@ -14,7 +12,8 @@ public:
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
};

View File

@@ -2,7 +2,7 @@
#define POINCARE_GLOBAL_CONTEXT_H
#include <poincare/context.h>
#include <poincare/float.h>
#include <poincare/complex.h>
class Integer;
@@ -18,12 +18,12 @@ public:
static constexpr uint16_t k_maxNumberOfScalarExpressions = 26;
static constexpr uint16_t k_maxNumberOfListExpressions = 10;
static constexpr uint16_t k_maxNumberOfMatrixExpressions = 10;
static Float * defaultExpression();
static Complex * defaultExpression();
private:
int symbolIndex(const Symbol * symbol) const;
Expression * m_expressions[k_maxNumberOfScalarExpressions];
Float m_pi;
Float m_e;
Complex m_pi;
Complex m_e;
};
#endif

View File

@@ -2,7 +2,7 @@
#define POINCARE_MATRIX_H
#include <poincare/expression.h>
#include <poincare/integer.h>
#include <poincare/complex.h>
#include <poincare/matrix_data.h>
class Matrix : public Expression {
@@ -26,7 +26,7 @@ class Matrix : public Expression {
int writeTextInBuffer(char * buffer, int bufferSize) override;
private:
MatrixData * m_matrixData;
static Integer * defaultExpression();
static Complex * defaultExpression();
};
#endif

View File

@@ -2,7 +2,7 @@
#define POINCARE_MATRIX_DATA_H
#include <poincare/list_data.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include <poincare/expression.h>
class MatrixData {
@@ -18,7 +18,7 @@ class MatrixData {
int m_numberOfRows;
int m_numberOfColumns;
Expression ** m_operands;
static Float * defaultExpression();
static Complex * defaultExpression();
};
#endif

View File

@@ -2,21 +2,18 @@
#define POINCARE_MULTIPLICATION_H
#include <poincare/binary_operation.h>
#include <poincare/float.h>
#include <poincare/matrix.h>
class Multiplication : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
Type type() const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
public:
Type type() const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
};
#endif

View File

@@ -11,6 +11,7 @@ public:
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
};
#endif

View File

@@ -3,7 +3,6 @@
#include <poincare/expression.h>
#include <poincare/matrix.h>
#include <poincare/float.h>
class Opposite : public Expression {
public:

View File

@@ -1,21 +1,21 @@
#ifndef POINCARE_POWER_H
#define POINCARE_POWER_H
#include <poincare/float.h>
#include <poincare/matrix.h>
#include <poincare/binary_operation.h>
class Power : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const override;
public:
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
};
#endif

View File

@@ -11,6 +11,7 @@ public:
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
};
#endif

View File

@@ -11,6 +11,7 @@ public:
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
};
#endif

View File

@@ -1,23 +1,19 @@
#ifndef POINCARE_SUBSTRACTION_H
#define POINCARE_SUBSTRACTION_H
#include <poincare/float.h>
#include <poincare/matrix.h>
#include <poincare/binary_operation.h>
class Subtraction : public BinaryOperation {
using BinaryOperation::BinaryOperation;
public:
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnFloatAndMatrix(Float * f, Matrix * m, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const override;
public:
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
float approximate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
Type type() const override;
Expression * cloneWithDifferentOperands(Expression** newOperands,
int numnerOfOperands, bool cloneOperands = true) const override;
private:
Expression * evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const override;
Expression * evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const override;
};
#endif

View File

@@ -11,6 +11,7 @@ public:
Expression * cloneWithDifferentOperands(Expression ** newOperands,
int numberOfOperands, bool cloneOperands = true) const override;
ExpressionLayout * createLayout(DisplayMode displayMode = DisplayMode::Auto) const override;
Expression * evaluate(Context& context, AngleUnit angleUnit = AngleUnit::Radian) const override;
};
#endif

View File

@@ -2,7 +2,7 @@
#define POINCARE_VARIABLE_CONTEXT_H
#include <poincare/context.h>
#include <poincare/float.h>
#include <poincare/complex.h>
class VariableContext : public Context {
public:
@@ -11,7 +11,7 @@ public:
const Expression * expressionForSymbol(const Symbol * symbol) override;
private:
char m_name;
Float m_value;
Complex m_value;
Context * m_parentContext;
};

View File

@@ -1,4 +1,5 @@
#include <poincare/absolute_value.h>
#include <poincare/complex.h>
#include "layout/absolute_value_layout.h"
extern "C" {
@@ -25,7 +26,29 @@ Expression * AbsoluteValue::cloneWithDifferentOperands(Expression** newOperands,
}
float AbsoluteValue::approximate(Context& context, AngleUnit angleUnit) const {
return fabsf(m_args[0]->approximate(context, angleUnit));
Expression * evaluation = evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
float result = 0.0f;
if (evaluation->type() == Type::Matrix) {
result = NAN;
} else {
result = ((Complex *)evaluation)->absoluteValue();
}
delete evaluation;
return result;
}
Expression * AbsoluteValue::evaluate(Context& context, AngleUnit angleUnit) const {
Expression * evaluation = m_args[0]->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Matrix) {
delete evaluation;
return new Complex(NAN);
}
float absVal = ((Complex *)evaluation)->absoluteValue();
Complex * result = new Complex(absVal);
delete evaluation;
return result;
}
ExpressionLayout * AbsoluteValue::createLayout(DisplayMode displayMode) const {

View File

@@ -32,25 +32,6 @@ bool Addition::isCommutative() const {
return true;
}
Expression * Addition::evaluateOnMatrixAndFloat(Matrix * m, Float * f, Context& context, AngleUnit angleUnit) const {
return evaluateOnFloatAndMatrix(f, m, context, angleUnit);
}
Expression * Addition::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(a->approximate(context, angleUnit) + m->operand(i)->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}
Expression * Addition::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) {
return nullptr;
}
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) + n->operand(i)->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
Expression * Addition::evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const {
return new Complex(c->a()+ d->a(), c->b() + d->b());
}

View File

@@ -1,6 +1,7 @@
#include <poincare/binary_operation.h>
extern "C" {
#include <assert.h>
#include <math.h>
}
BinaryOperation::BinaryOperation(Expression ** operands, bool cloneOperands) {
@@ -42,14 +43,14 @@ Expression * BinaryOperation::evaluate(Context& context, AngleUnit angleUnit) co
return nullptr;
}
Expression * result = nullptr;
if (leftOperandEvalutation->type() == Type::Float && rightOperandEvalutation->type() == Type::Float) {
result = new Float(this->approximate(context, angleUnit));
if (leftOperandEvalutation->type() == Type::Complex && rightOperandEvalutation->type() == Type::Complex) {
result = evaluateOnComplex((Complex *)leftOperandEvalutation, (Complex *)rightOperandEvalutation, context, angleUnit);
}
if (leftOperandEvalutation->type() == Type::Matrix && rightOperandEvalutation->type() == Type::Float) {
result = evaluateOnMatrixAndFloat((Matrix *)leftOperandEvalutation, (Float *)rightOperandEvalutation, context, angleUnit);
if (leftOperandEvalutation->type() == Type::Complex && rightOperandEvalutation->type() == Type::Matrix) {
result = evaluateOnComplexAndMatrix((Complex *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit);
}
if (leftOperandEvalutation->type() == Type::Float && rightOperandEvalutation->type() == Type::Matrix) {
result = evaluateOnFloatAndMatrix((Float *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit);
if (leftOperandEvalutation->type() == Type::Matrix && rightOperandEvalutation->type() == Type::Complex) {
result = evaluateOnMatrixAndComplex((Matrix *)leftOperandEvalutation, (Complex *)rightOperandEvalutation, context, angleUnit);
}
if (leftOperandEvalutation->type() == Type::Matrix && rightOperandEvalutation->type() == Type::Matrix) {
result = evaluateOnMatrices((Matrix *)leftOperandEvalutation, (Matrix *)rightOperandEvalutation, context, angleUnit);
@@ -59,14 +60,45 @@ Expression * BinaryOperation::evaluate(Context& context, AngleUnit angleUnit) co
return result;
}
Expression * BinaryOperation::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const {
return nullptr;
Expression * BinaryOperation::evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
Expression * evaluation = m->operand(i)->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Matrix) {
operands[i] = new Complex(NAN);
delete evaluation;
continue;
}
operands[i] = evaluateOnComplex((Complex *)evaluation, c, context, angleUnit);
delete evaluation;
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}
Expression * BinaryOperation::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const {
return nullptr;
Expression * BinaryOperation::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
return evaluateOnMatrixAndComplex(m, c, context, angleUnit);
}
Expression * BinaryOperation::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
return nullptr;
if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) {
return nullptr;
}
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
Expression * mEvaluation = m->operand(i)->evaluate(context, angleUnit);
Expression * nEvaluation = n->operand(i)->evaluate(context, angleUnit);
assert(mEvaluation->type() == Type::Matrix || mEvaluation->type() == Type::Complex);
assert(nEvaluation->type() == Type::Matrix || nEvaluation->type() == Type::Complex);
if (mEvaluation->type() == Type::Matrix ||nEvaluation->type() == Type::Matrix) {
operands[i] = new Complex(NAN);
delete mEvaluation;
delete nEvaluation;
continue;
}
operands[i] = evaluateOnComplex((Complex *)mEvaluation, (Complex *)nEvaluation, context, angleUnit);
delete mEvaluation;
delete nEvaluation;
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}

View File

@@ -1,3 +1,4 @@
#include <poincare/complex.h>
extern "C" {
#include <assert.h>
#include <stdlib.h>
@@ -5,14 +6,16 @@ extern "C" {
#include <math.h>
}
#include "layout/string_layout.h"
#include <poincare/float.h>
#include <ion.h>
Float::Float(float f) :
m_float(f),
Complex::Complex(float a, float b) :
m_a(a),
m_b(b),
m_numberOfSignificantDigits(7)
{
}
static inline float setSign(float f, bool negative) {
if (negative) {
return -f;
@@ -34,79 +37,111 @@ float digitsToFloat(const char * digits, int length) {
return result;
}
Float::Float(const char * integralPart, int integralPartLength, bool integralNegative,
Complex::Complex(const char * integralPart, int integralPartLength, bool integralNegative,
const char * fractionalPart, int fractionalPartLength,
const char * exponent, int exponentLength, bool exponentNegative) {
float i = digitsToFloat(integralPart, integralPartLength);
float j = digitsToFloat(fractionalPart, fractionalPartLength);
float l = setSign(digitsToFloat(exponent, exponentLength), exponentNegative);
m_float = setSign((i + j*powf(10.0f, -ceilf(fractionalPartLength)))* powf(10.0f, l), integralNegative);
m_a = setSign((i + j*powf(10.0f, -ceilf(fractionalPartLength)))* powf(10.0f, l), integralNegative);
m_b = 0.0f;
m_numberOfSignificantDigits = 7;
}
void Float::setNumberOfSignificantDigits(int numberOfDigits) {
void Complex::setNumberOfSignificantDigits(int numberOfDigits) {
m_numberOfSignificantDigits = numberOfDigits;
}
Expression * Float::clone() const {
return new Float(m_float);
Expression * Complex::clone() const {
return new Complex(m_a, m_b);
}
float Float::approximate(Context& context, AngleUnit angleUnit) const {
return m_float;
float Complex::approximate(Context& context, AngleUnit angleUnit) const {
if (m_b == 0.0f) {
return m_a;
}
return NAN;
}
Expression * Float::evaluate(Context& context, AngleUnit angleUnit) const {
Expression * Complex::evaluate(Context& context, AngleUnit angleUnit) const {
return clone();
}
Expression::Type Float::type() const {
return Type::Float;
Expression::Type Complex::type() const {
return Type::Complex;
}
ExpressionLayout * Float::createLayout(DisplayMode displayMode) const {
char buffer[k_maxBufferLength];
convertFloatToText(buffer, k_maxBufferLength, m_numberOfSignificantDigits, displayMode);
int size = 0;
while (buffer[size] != 0) {
size++;
}
return new StringLayout(buffer, size);
ExpressionLayout * Complex::createLayout(DisplayMode displayMode) const {
char buffer[k_maxComplexBufferLength];
int numberOfChars = convertComplexToText(buffer, k_maxComplexBufferLength, displayMode);
return new StringLayout(buffer, numberOfChars);
}
bool Float::valueEquals(const Expression * e) const {
assert(e->type() == Expression::Type::Float);
return m_float == ((Float *)e)->m_float;
int Complex::writeTextInBuffer(char * buffer, int bufferSize) {
return convertComplexToText(buffer, bufferSize, DisplayMode::Auto);
}
int Float::writeTextInBuffer(char * buffer, int bufferSize) {
return convertFloatToText(buffer, bufferSize, m_numberOfSignificantDigits, DisplayMode::Auto);
float Complex::a() {
return m_a;
}
int Float::convertFloatToText(char * buffer, int bufferSize,
int numberOfSignificantDigits, DisplayMode mode) const {
char tempBuffer[k_maxBufferLength];
int requiredLength = convertFloatToTextPrivate(tempBuffer, numberOfSignificantDigits, mode);
float Complex::b() {
return m_b;
}
float Complex::absoluteValue() {
return sqrtf(m_a*m_a+m_b*m_b);
}
int Complex::convertFloatToText(float f, char * buffer, int bufferSize,
int numberOfSignificantDigits, DisplayMode mode) {
char tempBuffer[k_maxFloatBufferLength];
int requiredLength = convertFloatToTextPrivate(f, tempBuffer, numberOfSignificantDigits, mode);
/* if the required buffer size overflows the buffer size, we first force the
* display mode to scientific and decrease the number of significant digits to
* fit the buffer size. If the buffer size is still to small, we only write
* the beginning of the float and truncate it (which can result in a non sense
* text) */
if (mode == DisplayMode::Auto && requiredLength >= bufferSize) {
requiredLength = convertFloatToTextPrivate(tempBuffer, numberOfSignificantDigits, DisplayMode::Scientific);
requiredLength = convertFloatToTextPrivate(f, tempBuffer, numberOfSignificantDigits, DisplayMode::Scientific);
}
if (requiredLength >= bufferSize) {
requiredLength = convertFloatToTextPrivate(tempBuffer, numberOfSignificantDigits - requiredLength + bufferSize - 1, DisplayMode::Scientific);
requiredLength = convertFloatToTextPrivate(f, tempBuffer, numberOfSignificantDigits - requiredLength + bufferSize - 1, DisplayMode::Scientific);
}
requiredLength = requiredLength < bufferSize ? requiredLength : bufferSize;
strlcpy(buffer, tempBuffer, bufferSize);
return requiredLength;
}
int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigits, DisplayMode mode) const {
if (isinf(m_float)) {
buffer[0] = m_float > 0 ? '+' : '-';
int Complex::convertComplexToText(char * buffer, int bufferSize, DisplayMode displayMode) const {
int numberOfChars = 0;
if (m_a != 0.0f || m_b == 0.0f) {
numberOfChars = convertFloatToText(m_a, buffer, bufferSize, m_numberOfSignificantDigits, displayMode);
if (m_b > 0.0f && bufferSize > numberOfChars+1) {
buffer[numberOfChars++] = '+';
// Ensure that the string is null terminated even if buffer size is to small
buffer[numberOfChars] = 0;
}
}
if (m_b != 1.0f && m_b != -1.0f && m_b != 0.0f) {
numberOfChars += convertFloatToText(m_b, buffer+numberOfChars, bufferSize-numberOfChars, m_numberOfSignificantDigits, displayMode);
buffer[numberOfChars++] = '*';
}
if (m_b == -1.0f && bufferSize > numberOfChars+1) {
buffer[numberOfChars++] = '-';
}
if (m_b != 0.0f && bufferSize > numberOfChars+1) {
buffer[numberOfChars++] = Ion::Charset::SmallIota;
buffer[numberOfChars] = 0;
}
return numberOfChars;
}
int Complex::convertFloatToTextPrivate(float f, char * buffer, int numberOfSignificantDigits, DisplayMode mode) {
if (isinf(f)) {
buffer[0] = f > 0 ? '+' : '-';
buffer[1] = 'I';
buffer[2] = 'n';
buffer[3] = 'f';
@@ -114,7 +149,7 @@ int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigit
return 5;
}
if (isnan(m_float)) {
if (isnan(f)) {
buffer[0] = 'N';
buffer[1] = 'a';
buffer[2] = 'N';
@@ -122,9 +157,9 @@ int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigit
return 4;
}
float logBase10 = m_float != 0.0f ? log10f(fabsf(m_float)) : 0;
float logBase10 = f != 0.0f ? log10f(fabsf(f)) : 0;
int exponentInBase10 = logBase10;
if ((int)m_float == 0 && logBase10 != exponentInBase10) {
if ((int)f == 0 && logBase10 != exponentInBase10) {
/* For floats < 0, the exponent in base 10 is the inferior integer part of
* log10(float). We thus decrement the exponent for float < 0 whose exponent
* is not an integer. */
@@ -141,7 +176,7 @@ int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigit
// Number of char available for the mantissa
int availableCharsForMantissaWithoutSign = numberOfSignificantDigits + 1;
int availableCharsForMantissaWithSign = m_float >= 0 ? availableCharsForMantissaWithoutSign : availableCharsForMantissaWithoutSign + 1;
int availableCharsForMantissaWithSign = f >= 0 ? availableCharsForMantissaWithoutSign : availableCharsForMantissaWithoutSign + 1;
// Compute mantissa
/* The number of digits in an integer is capped because the maximal integer is
@@ -151,7 +186,7 @@ int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigit
assert(availableCharsForMantissaWithoutSign - 1 < numberMaximalOfCharsInInteger);
int numberOfDigitBeforeDecimal = exponentInBase10 >= 0 || displayMode == DisplayMode::Scientific ?
exponentInBase10 + 1 : 1;
int mantissa = roundf(m_float * powf(10, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal));
int mantissa = roundf(f * powf(10, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal));
// Correct the number of digits in mantissa after rounding
int mantissaExponentInBase10 = exponentInBase10 > 0 || displayMode == DisplayMode::Scientific ? availableCharsForMantissaWithoutSign - 1 : availableCharsForMantissaWithoutSign + exponentInBase10;
if ((int)(mantissa * powf(10, - mantissaExponentInBase10)) > 0) {
@@ -198,7 +233,7 @@ int Float::convertFloatToTextPrivate(char * buffer, int numberOfSignificantDigit
return (availableCharsForMantissaWithSign+1+numberOfCharExponent);
}
void Float::printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, int i, int decimalMarkerPosition) {
void Complex::printBase10IntegerWithDecimalMarker(char * buffer, int bufferSize, int i, int decimalMarkerPosition) {
/* The decimal marker position is always preceded by a char, thus, it is never
* in first position. When called by convertFloatToText, the buffer length is
* always > 0 as we asserted a minimal number of available chars. */

View File

@@ -29,3 +29,5 @@ float Cosine::approximate(Context& context, AngleUnit angleUnit) const {
}
return cosf(m_args[0]->approximate(context, angleUnit));
}
//TODO: implement evaluate to handle cos complex

View File

@@ -1,6 +1,6 @@
#include <poincare/derivative.h>
#include <poincare/symbol.h>
#include <poincare/float.h>
#include <poincare/complex.h>
extern "C" {
#include <assert.h>
@@ -30,10 +30,15 @@ float Derivative::approximate(Context& context, AngleUnit angleUnit) const {
VariableContext xContext = VariableContext('x', &context);
Symbol xSymbol = Symbol('x');
float x = m_args[1]->approximate(context, angleUnit);
Float e = Float(x);
Complex e = Complex(x);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float functionValue = m_args[0]->approximate(xContext, angleUnit);
// No complex/matrix version of Derivative
if (isnan(x) || isnan(functionValue)) {
return NAN;
}
/* Ridders' Algorithm
* Blibliography:
* - Press, W. H., Teukolsky, S. A., Vetterling, W. T., & Flannery, B. P.
@@ -87,7 +92,6 @@ float Derivative::approximate(Context& context, AngleUnit angleUnit) const {
break;
}
}
err = powf(10.0f, (int)log10f(fabsf(err))+2.0f);
/* if the error is too big regarding the value, do not return the answer */
if (err/ans > k_maxErrorRateOnApproximation || isnan(err)) {
return NAN;
@@ -95,15 +99,16 @@ float Derivative::approximate(Context& context, AngleUnit angleUnit) const {
if (err < FLT_MIN) {
return ans;
}
err = powf(10.0f, (int)log10f(fabsf(err))+2.0f);
return roundf(ans/err)*err;
}
float Derivative::growthRateAroundAbscissa(float x, float h, VariableContext xContext, AngleUnit angleUnit) const {
Symbol xSymbol = Symbol('x');
Float e = Float(x + h);
Complex e = Complex(x + h, 0.0f);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float expressionPlus = m_args[0]->approximate(xContext, angleUnit);
e = Float(x-h);
e = Complex(x-h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float expressionMinus = m_args[0]->approximate(xContext, angleUnit);
return (expressionPlus - expressionMinus)/(2*h);
@@ -111,13 +116,13 @@ float Derivative::growthRateAroundAbscissa(float x, float h, VariableContext xCo
float Derivative::approximateDerivate2(float x, float h, VariableContext xContext, AngleUnit angleUnit) const {
Symbol xSymbol = Symbol('x');
Float e = Float(x + h);
Complex e = Complex(x + h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float expressionPlus = m_args[0]->approximate(xContext, angleUnit);
e = Float(x);
e = Complex(x);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float expression = m_args[0]->approximate(xContext, angleUnit);
e = Float(x-h);
e = Complex(x-h);
xContext.setExpressionForSymbolName(&e, &xSymbol);
float expressionMinus = m_args[0]->approximate(xContext, angleUnit);
return expressionPlus - 2.0f*expression + expressionMinus;

View File

@@ -98,6 +98,7 @@ sum { poincare_expression_yylval.expression = new Sum(); return FUNCTION; }
product { poincare_expression_yylval.expression = new Product(); return FUNCTION; }
\xa0 { poincare_expression_yylval.character = yytext[0]; return SYMBOL; }
\xa5 { poincare_expression_yylval.expression = new SquareRoot(); return FUNCTION; }
\x9d { return ICOMPLEX; }
e { poincare_expression_yylval.character = yytext[0]; return SYMBOL; }
\+ { return PLUS; }
\- { return MINUS; }

View File

@@ -47,9 +47,9 @@ void poincare_expression_yyerror(Expression ** expressionOutput, char const *msg
/* The INTEGER token uses the "string" part of the union to store its value */
%token <string> DIGITS
%token <string> FLOAT
%token <character> SYMBOL
%token <function> FUNCTION
%token <complex> ICOMPLEX
/* Operator tokens */
%token PLUS
@@ -112,12 +112,13 @@ mtxData:
number:
DIGITS { $$ = new Integer($1.address, false); }
| DIGITS DOT DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, nullptr, 0, false); }
| DIGITS DOT DIGITS EE DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, $5.address, $5.length, false); }
| DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Float($1.address, $1.length, false, $3.address, $3.length, $6.address, $6.length, true); }
| DIGITS DOT DIGITS { $$ = new Complex($1.address, $1.length, false, $3.address, $3.length, nullptr, 0, false); }
| DIGITS DOT DIGITS EE DIGITS { $$ = new Complex($1.address, $1.length, false, $3.address, $3.length, $5.address, $5.length, false); }
| DIGITS DOT DIGITS EE MINUS DIGITS { $$ = new Complex($1.address, $1.length, false, $3.address, $3.length, $6.address, $6.length, true); }
exp:
number { $$ = $1; }
| ICOMPLEX { $$ = new Complex(0.0f, 1.0f); }
| SYMBOL { $$ = new Symbol($1); }
| exp PLUS exp { Expression * terms[2] = {$1,$3}; $$ = new Addition(terms, false); }
| exp MINUS exp { Expression * terms[2] = {$1,$3}; $$ = new Subtraction(terms, false); }

View File

@@ -18,7 +18,6 @@ ExpressionLayout * Fraction::createLayout(DisplayMode displayMode) const {
}
float Fraction::approximate(Context& context, AngleUnit angleUnit) const {
// TODO: handle division by zero
return m_operands[0]->approximate(context, angleUnit)/m_operands[1]->approximate(context, angleUnit);
}
@@ -26,13 +25,13 @@ Expression::Type Fraction::type() const {
return Type::Fraction;
}
Expression * Fraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(m->operand(i)->approximate(context, angleUnit)/a->approximate(context, angleUnit));
}
Expression * result = new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
return result;
Expression * Fraction::evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const {
float norm = d->a()*d->a() + d->b()*d->b();
return new Complex((c->a()*d->a()+c->b()*d->b())/norm, (d->a()*c->b()-c->a()*d->b())/norm);
}
Expression * Fraction::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
return nullptr;
}
Expression * Fraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
@@ -41,9 +40,9 @@ Expression * Fraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& conte
}
/* TODO: implement matrix fraction
if (n->det() == 0) {
return new Float(NAN);
return new Complex(NAN);
}
result = new Product(m, n->inv());
result = new Product(m, n->inv(), false);
return result;*/
return nullptr;
}

View File

@@ -3,7 +3,7 @@ extern "C" {
#include <stdlib.h>
}
#include <poincare/function.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include "layout/horizontal_layout.h"
#include "layout/parenthesis_layout.h"
#include "layout/string_layout.h"
@@ -90,5 +90,6 @@ int Function::numberOfOperands() const {
}
Expression * Function::evaluate(Context& context, AngleUnit angleUnit) const {
return new Float(approximate(context, angleUnit));
/* Default function evaluation works for reel function */
return new Complex(approximate(context, angleUnit));
}

View File

@@ -4,16 +4,16 @@
#include <ion.h>
GlobalContext::GlobalContext() :
m_pi(Float(M_PI)),
m_e(Float(M_E))
m_pi(Complex(M_PI)),
m_e(Complex(M_E))
{
for (int i = 0; i < k_maxNumberOfScalarExpressions; i++) {
m_expressions[i] = nullptr;
}
}
Float * GlobalContext::defaultExpression() {
static Float * defaultExpression = new Float(0);
Complex * GlobalContext::defaultExpression() {
static Complex * defaultExpression = new Complex(0.0f);
return defaultExpression;
}
@@ -41,6 +41,6 @@ const Expression * GlobalContext::expressionForSymbol(const Symbol * symbol) {
void GlobalContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {
int index = symbolIndex(symbol);
assert(expression->type() == Expression::Type::Float);
assert(expression->type() == Expression::Type::Complex);
m_expressions[index] = expression;
}

View File

@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include "layout/string_layout.h"
#define MAX(a,b) ((a)>(b)?a:b)
@@ -309,7 +309,7 @@ float Integer::approximate(Context& context, AngleUnit angleUnit) const {
}
Expression * Integer::evaluate(Context& context, AngleUnit angleUnit) const {
return new Float(approximate(context, angleUnit));
return new Complex(approximate(context, angleUnit));
}
Expression::Type Integer::type() const {

View File

@@ -1,6 +1,6 @@
#include <poincare/integral.h>
#include <poincare/symbol.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include <poincare/context.h>
extern "C" {
#include <assert.h>
@@ -34,6 +34,9 @@ float Integral::approximate(Context& context, AngleUnit angleUnit) const {
VariableContext xContext = VariableContext('x', &context);
float a = m_args[1]->approximate(context, angleUnit);
float b = m_args[2]->approximate(context, angleUnit);
if (isnan(a) || isnan(b)) {
return NAN;
}
#ifdef LAGRANGE_METHOD
return lagrangeGaussQuadrature(a, b, xContext, angleUnit);
#else
@@ -49,7 +52,7 @@ ExpressionLayout * Integral::createLayout(DisplayMode displayMode) const {
}
float Integral::functionValueAtAbscissa(float x, VariableContext xContext, AngleUnit angleUnit) const {
Float e = Float(x);
Complex e = Complex(x);
Symbol xSymbol = Symbol('x');
xContext.setExpressionForSymbolName(&e, &xSymbol);
return m_args[0]->approximate(xContext, angleUnit);

View File

@@ -3,7 +3,7 @@ extern "C" {
#include <stdlib.h>
}
#include <poincare/matrix.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include "layout/matrix_layout.h"
#include <math.h>
#include <string.h>
@@ -22,8 +22,8 @@ Matrix::Matrix(Expression ** newOperands, int numberOfOperands, int numberOfColu
m_matrixData = new MatrixData(newOperands, numberOfOperands, numberOfColumns, numberOfRows, cloneOperands);
}
Integer * Matrix::defaultExpression() {
static Integer * defaultExpression = new Integer(0);
Complex * Matrix::defaultExpression() {
static Complex * defaultExpression = new Complex(0.0f);
return defaultExpression;
}
@@ -56,7 +56,13 @@ float Matrix::approximate(Context& context, AngleUnit angleUnit) const {
Expression * Matrix::evaluate(Context& context, AngleUnit angleUnit) const {
Expression * operands[numberOfOperands()];
for (int i = 0; i < numberOfOperands(); i++) {
operands[i] = new Float(operand(i)->approximate(context, angleUnit));
operands[i] = operand(i)->evaluate(context, angleUnit);
assert(operands[i]->type() == Type::Matrix || operands[i]->type() == Type::Complex);
if (operands[i]->type() == Type::Matrix) {
delete operands[i];
operands[i] = new Complex(NAN);
continue;
}
}
return new Matrix(new MatrixData(operands, numberOfOperands(), numberOfColumns(), numberOfRows(), false));
}

View File

@@ -32,8 +32,8 @@ MatrixData::MatrixData(Expression ** newOperands, int numberOfOperands, int numb
}
}
Float * MatrixData::defaultExpression() {
static Float * defaultExpression = new Float(0.0f);
Complex * MatrixData::defaultExpression() {
static Complex * defaultExpression = new Complex(0.0f);
return defaultExpression;
}

View File

@@ -1,6 +1,7 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
#include <math.h>
}
#include <poincare/multiplication.h>
@@ -31,16 +32,8 @@ Expression * Multiplication::cloneWithDifferentOperands(Expression** newOperands
return new Multiplication(newOperands, cloneOperands);
}
Expression * Multiplication::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(m->operand(i)->approximate(context, angleUnit)*a->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}
Expression * Multiplication::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const {
return evaluateOnMatrixAndFloat(m, a, context, angleUnit);
Expression * Multiplication::evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const {
return new Complex(c->a()*d->a()-c->b()*d->b(), c->b()*d->a() + c->a()*d->b());
}
Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
@@ -50,11 +43,25 @@ Expression * Multiplication::evaluateOnMatrices(Matrix * m, Matrix * n, Context&
Expression * operands[m->numberOfRows() * n->numberOfColumns()];
for (int i = 0; i < m->numberOfRows(); i++) {
for (int j = 0; j < n->numberOfColumns(); j++) {
float f = 0.0f;
float a = 0.0f;
float b = 0.0f;
for (int k = 0; k < m->numberOfColumns(); k++) {
f += m->operand(i*m->numberOfColumns()+k)->approximate(context, angleUnit) * n->operand(k*n->numberOfColumns()+j)->approximate(context, angleUnit);
Expression * mEvaluation = m->operand(i*m->numberOfColumns()+k)->evaluate(context, angleUnit);
Expression * nEvaluation = n->operand(k*n->numberOfColumns()+j)->evaluate(context, angleUnit);
assert(mEvaluation->type() == Type::Matrix || mEvaluation->type() == Type::Complex);
assert(nEvaluation->type() == Type::Matrix || nEvaluation->type() == Type::Complex);
if (mEvaluation->type() == Type::Matrix ||nEvaluation->type() == Type::Matrix) {
operands[i] = new Complex(NAN);
delete mEvaluation;
delete nEvaluation;
continue;
}
a += ((Complex *)mEvaluation)->a()*((Complex *)nEvaluation)->a() - ((Complex *)mEvaluation)->b()*((Complex *)nEvaluation)->b();
b += ((Complex *)mEvaluation)->b()*((Complex *)nEvaluation)->a() + ((Complex *)mEvaluation)->a()*((Complex *)nEvaluation)->b();
delete mEvaluation;
delete nEvaluation;
}
operands[i*n->numberOfColumns()+j] = new Float(f);
operands[i*n->numberOfColumns()+j] = new Complex(a, b);
}
}
return new Matrix(operands, m->numberOfRows() * n->numberOfColumns(), m->numberOfRows(), n->numberOfColumns(), false);

View File

@@ -1,4 +1,7 @@
#include <poincare/nth_root.h>
#include <poincare/complex.h>
#include <poincare/fraction.h>
#include <poincare/power.h>
#include "layout/nth_root_layout.h"
extern "C" {
@@ -30,4 +33,32 @@ float NthRoot::approximate(Context& context, AngleUnit angleUnit) const {
ExpressionLayout * NthRoot::createLayout(DisplayMode displayMode) const {
return new NthRootLayout(m_args[0]->createLayout(displayMode), m_args[1]->createLayout(displayMode));
}
Expression * NthRoot::evaluate(Context& context, AngleUnit angleUnit) const {
Expression * baseEvaluation = m_args[0]->evaluate(context, angleUnit);
Expression * indexEvaluation = m_args[1]->evaluate(context, angleUnit);
assert(baseEvaluation->type() == Type::Matrix || baseEvaluation->type() == Type::Complex);
assert(indexEvaluation->type() == Type::Matrix || indexEvaluation->type() == Type::Complex);
if (baseEvaluation->type() == Type::Matrix || indexEvaluation->type() == Type::Matrix) {
delete baseEvaluation;
delete indexEvaluation;
return new Complex(NAN);
}
Expression * operands[2];
operands[0] = baseEvaluation;
Expression * operandChildren[2];
operandChildren[0] = new Complex(1.0f);
operandChildren[1] = indexEvaluation;
Expression * fraction = new Fraction(operandChildren, true);
operands[1] = fraction->evaluate(context, angleUnit);
Expression * power = new Power(operands, true);
Expression * newResult = power->evaluate(context, angleUnit);
delete baseEvaluation;
delete operandChildren[0];
delete indexEvaluation;
delete fraction;
delete operands[1];
delete power;
return newResult;
}

View File

@@ -2,6 +2,7 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
#include <math.h>
}
#include "layout/horizontal_layout.h"
#include "layout/parenthesis_layout.h"
@@ -39,8 +40,8 @@ Expression * Opposite::evaluate(Context& context, AngleUnit angleUnit) const {
return nullptr;
}
Expression * result = nullptr;
if (operandEvalutation->type() == Type::Float) {
result = new Float(this->approximate(context, angleUnit));
if (operandEvalutation->type() == Type::Complex) {
result = new Complex(-((Complex *)operandEvalutation)->a(), -((Complex *)operandEvalutation)->b());
}
if (operandEvalutation->type() == Type::Matrix) {
result = evaluateOnMatrix((Matrix *)operandEvalutation, context, angleUnit);
@@ -75,7 +76,15 @@ Expression * Opposite::cloneWithDifferentOperands(Expression** newOperands,
Expression * Opposite::evaluateOnMatrix(Matrix * m, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(- m->operand(i)->approximate(context, angleUnit));
Expression * evaluation = m->operand(i)->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Matrix) {
operands[i] = new Complex(NAN);
delete evaluation;
continue;
}
operands[i] = new Complex(-((Complex *)evaluation)->a(), -((Complex *)evaluation)->b());
delete evaluation;
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}

View File

@@ -10,29 +10,6 @@ float Power::approximate(Context& context, AngleUnit angleUnit) const {
return powf(m_operands[0]->approximate(context, angleUnit), m_operands[1]->approximate(context, angleUnit));
}
Expression * Power::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const {
if (m_operands[1]->type() != Expression::Type::Integer) {
return nullptr;
}
if (m->numberOfColumns() != m->numberOfRows()) {
return nullptr;
}
// TODO: return identity matrix if i == 0
int power = a->approximate(context, angleUnit);
Expression * result = new Float(1);
for (int k = 0; k < power; k++) {
Expression * operands[2];
operands[0] = result;
operands[1] = m;
Expression * multiplication = new Multiplication(operands, true);
Expression * newResult = multiplication->evaluate(context, angleUnit);
delete result;
result = newResult;
delete multiplication;
}
return result;
}
Expression::Type Power::type() const {
return Type::Power;
}
@@ -51,3 +28,40 @@ ExpressionLayout * Power::createLayout(DisplayMode displayMode) const {
}
return new BaselineRelativeLayout(m_operands[0]->createLayout(displayMode),indiceOperand->createLayout(displayMode), BaselineRelativeLayout::Type::Superscript);
}
Expression * Power::evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const {
/* Check that d is a reel number first */
//TODO: implement r^(1/n)*e^(i*Pi/n)
return new Complex(0.0f);
}
Expression * Power::evaluateOnMatrixAndComplex(Matrix * m, Complex * c, Context& context, AngleUnit angleUnit) const {
if (m_operands[1]->type() != Expression::Type::Integer) {
return nullptr;
}
if (m->numberOfColumns() != m->numberOfRows()) {
return nullptr;
}
// TODO: return identity matrix if i == 0
int power = c->approximate(context, angleUnit);
Expression * result = new Complex(1);
for (int k = 0; k < power; k++) {
Expression * operands[2];
operands[0] = result;
operands[1] = m;
Expression * multiplication = new Multiplication(operands, true);
Expression * newResult = multiplication->evaluate(context, angleUnit);
delete result;
result = newResult;
delete multiplication;
}
return result;
}
Expression * Power::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
return nullptr;
}
Expression * Power::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
return nullptr;
}

View File

@@ -1,6 +1,7 @@
#include <poincare/product.h>
#include <poincare/symbol.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include <poincare/multiplication.h>
#include <poincare/variable_context.h>
#include "layout/string_layout.h"
#include "layout/horizontal_layout.h"
@@ -8,6 +9,7 @@
extern "C" {
#include <assert.h>
#include <stdlib.h>
#include <math.h>
}
Product::Product() :
@@ -35,7 +37,7 @@ float Product::approximate(Context& context, AngleUnit angleUnit) const {
int end = m_args[2]->approximate(context, angleUnit);
float result = 1.0f;
for (int i = start; i <= end; i++) {
Float iExpression = Float(i);
Complex iExpression = Complex(i);
nContext.setExpressionForSymbolName(&iExpression, &nSymbol);
result = result*m_args[0]->approximate(nContext, angleUnit);
}
@@ -48,3 +50,28 @@ ExpressionLayout * Product::createLayout(DisplayMode displayMode) const {
childrenLayouts[1] = m_args[1]->createLayout(displayMode);
return new ProductLayout(new HorizontalLayout(childrenLayouts, 2), m_args[2]->createLayout(displayMode), m_args[0]->createLayout(displayMode));
}
Expression * Product::evaluate(Context& context, AngleUnit angleUnit) const {
float start = m_args[1]->approximate(context, angleUnit);
float end = m_args[2]->approximate(context, angleUnit);
if (isnan(start) || isnan(end)) {
return new Complex(NAN);
}
VariableContext nContext = VariableContext('n', &context);
Symbol nSymbol = Symbol('n');
Expression * result = new Complex(1);
for (int i = (int)start; i <= (int)end; i++) {
Complex iExpression = Complex(i);
nContext.setExpressionForSymbolName(&iExpression, &nSymbol);
Expression * operands[2];
operands[0] = result;
operands[1] = m_args[0]->evaluate(nContext, angleUnit);
Expression * multiplication = new Multiplication(operands, true);
Expression * newResult = multiplication->evaluate(context, angleUnit);
delete result;
delete operands[1];
result = newResult;
delete multiplication;
}
return result;
}

View File

@@ -29,3 +29,5 @@ float Sine::approximate(Context& context, AngleUnit angleUnit) const {
}
return sinf(m_args[0]->approximate(context, angleUnit));
}
//TODO: implement evaluate to handle sin complex

View File

@@ -1,6 +1,7 @@
#include <poincare/square_root.h>
#include <poincare/complex.h>
#include <poincare/power.h>
#include "layout/nth_root_layout.h"
extern "C" {
#include <assert.h>
#include <math.h>
@@ -30,4 +31,22 @@ float SquareRoot::approximate(Context& context, AngleUnit angleUnit) const {
ExpressionLayout * SquareRoot::createLayout(DisplayMode displayMode) const {
return new NthRootLayout(m_args[0]->createLayout(displayMode),nullptr);
}
}
Expression * SquareRoot::evaluate(Context& context, AngleUnit angleUnit) const {
Expression * evaluation = m_args[0]->evaluate(context, angleUnit);
assert(evaluation->type() == Type::Matrix || evaluation->type() == Type::Complex);
if (evaluation->type() == Type::Matrix) {
delete evaluation;
return new Complex(NAN);
}
Expression * operands[2];
operands[0] = evaluation;
operands[1] = new Complex(0.5f);
Expression * power = new Power(operands, true);
Expression * newResult = power->evaluate(context, angleUnit);
delete evaluation;
delete operands[1];
delete power;
return newResult;
}

View File

@@ -4,6 +4,7 @@ extern "C" {
}
#include <poincare/subtraction.h>
#include <poincare/opposite.h>
#include "layout/horizontal_layout.h"
#include "layout/string_layout.h"
#include "layout/parenthesis_layout.h"
@@ -32,32 +33,14 @@ ExpressionLayout * Subtraction::createLayout(DisplayMode displayMode) const {
return new HorizontalLayout(children_layouts, 3);
}
Expression * Subtraction::evaluateOnMatrixAndFloat(Matrix * m, Float * a, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) - a->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
Expression * Subtraction::evaluateOnComplex(Complex * c, Complex * d, Context& context, AngleUnit angleUnit) const {
return new Complex(c->a() - d->a(), c->b() - d->b());
}
Expression * Subtraction::evaluateOnFloatAndMatrix(Float * a, Matrix * m, Context& context, AngleUnit angleUnit) const {
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
operands[i] = new Float(a->approximate(context, angleUnit) - m->operand(i)->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
}
Expression * Subtraction::evaluateOnMatrices(Matrix * m, Matrix * n, Context& context, AngleUnit angleUnit) const {
if (m->numberOfColumns() != n->numberOfColumns() || m->numberOfRows() != n->numberOfRows()) {
return nullptr;
}
Expression * operands[m->numberOfRows() * m->numberOfColumns()];
for (int i = 0; i < m->numberOfRows() * m->numberOfColumns(); i++) {
if (!m->operand(i)->approximate(context, angleUnit) || !n->operand(i)->approximate(context, angleUnit)) {
return nullptr;
}
operands[i] = new Float(m->operand(i)->approximate(context, angleUnit) - n->operand(i)->approximate(context, angleUnit));
}
return new Matrix(operands, m->numberOfRows() * m->numberOfColumns(), m->numberOfColumns(), m->numberOfRows(), false);
Expression * Subtraction::evaluateOnComplexAndMatrix(Complex * c, Matrix * m, Context& context, AngleUnit angleUnit) const {
Expression * operand = evaluateOnMatrixAndComplex(m, c, context, angleUnit);
Opposite * opposite = new Opposite(operand, false);
Expression * result = opposite->evaluate(context, angleUnit);
delete opposite;
return result;
}

View File

@@ -1,12 +1,14 @@
#include <poincare/sum.h>
#include <poincare/symbol.h>
#include <poincare/float.h>
#include <poincare/complex.h>
#include <poincare/variable_context.h>
#include <poincare/addition.h>
#include "layout/sum_layout.h"
#include "layout/string_layout.h"
#include "layout/horizontal_layout.h"
extern "C" {
#include <assert.h>
#include <math.h>
#include <stdlib.h>
}
@@ -35,7 +37,7 @@ float Sum::approximate(Context& context, AngleUnit angleUnit) const {
int end = m_args[2]->approximate(context, angleUnit);
float result = 0.0f;
for (int i = start; i <= end; i++) {
Float iExpression = Float(i);
Complex iExpression = Complex(i);
nContext.setExpressionForSymbolName(&iExpression, &nSymbol);
result += m_args[0]->approximate(nContext, angleUnit);
}
@@ -48,3 +50,28 @@ ExpressionLayout * Sum::createLayout(DisplayMode displayMode) const {
childrenLayouts[1] = m_args[1]->createLayout(displayMode);
return new SumLayout(new HorizontalLayout(childrenLayouts, 2), m_args[2]->createLayout(displayMode), m_args[0]->createLayout(displayMode));
}
Expression * Sum::evaluate(Context& context, AngleUnit angleUnit) const {
float start = m_args[1]->approximate(context, angleUnit);
float end = m_args[2]->approximate(context, angleUnit);
if (isnan(start) || isnan(end)) {
return new Complex(NAN);
}
VariableContext nContext = VariableContext('n', &context);
Symbol nSymbol = Symbol('n');
Expression * result = new Complex(0.0f);
for (int i = (int)start; i <= (int)end; i++) {
Complex iExpression = Complex(i);
nContext.setExpressionForSymbolName(&iExpression, &nSymbol);
Expression * operands[2];
operands[0] = result;
operands[1] = m_args[0]->evaluate(nContext, angleUnit);
Expression * addition = new Addition(operands, true);
Expression * newResult = addition->evaluate(context, angleUnit);
delete result;
delete operands[1];
result = newResult;
delete addition;
}
return result;
}

View File

@@ -29,3 +29,5 @@ float Tangent::approximate(Context& context, AngleUnit angleUnit) const {
}
return tanf(m_args[0]->approximate(context, angleUnit));
}
//TODO: implement evaluate to handle tan complex

View File

@@ -1,17 +1,18 @@
#include <poincare/variable_context.h>
#include <assert.h>
VariableContext::VariableContext(char name, ::Context * parentContext) :
m_name(name),
m_value(Float(0.0f)),
m_value(Complex(0.0f)),
m_parentContext(parentContext)
{
}
void VariableContext::setExpressionForSymbolName(Expression * expression, const Symbol * symbol) {
if (symbol->name() == m_name) {
/* WARNING: we here assume that the expression does not content any function
* whose evaluation depends on the angle unit */
m_value = Float(expression->approximate(*m_parentContext));
assert(expression->type() == Expression::Type::Complex);
/* WARNING: We assume that the evaluation of expression is a reel */
m_value = Complex(expression->approximate(*m_parentContext));
} else {
m_parentContext->setExpressionForSymbolName(expression, symbol);
}

60
poincare/test/complex.cpp Normal file
View File

@@ -0,0 +1,60 @@
#include <quiz.h>
#include <poincare.h>
#include <string.h>
#include <assert.h>
QUIZ_CASE(poincare_complex_to_text) {
char buffer[14];
Complex::convertFloatToText(123.456f,buffer, 14, 7);
assert(strcmp(buffer, "1.23456E2") == 0);
Complex::convertFloatToText(1.234567891011f,buffer, 14, 7);
assert(strcmp(buffer, "1.234568E0") == 0);
Complex::convertFloatToText(2.0f, buffer, 14, 7);
assert(strcmp(buffer, "2.0E0") == 0);
Complex::convertFloatToText(123456789.0f, buffer, 14, 7);
assert(strcmp(buffer, "1.234568E8") == 0);
Complex::convertFloatToText(0.00000123456789f, buffer, 14, 7);
assert(strcmp(buffer, "1.234568E-6") == 0);
Complex::convertFloatToText(0.99f, buffer, 14, 7);
assert(strcmp(buffer, "9.9E-1") == 0);
Complex::convertFloatToText(-123.456789f, buffer, 14, 7);
assert(strcmp(buffer, "-1.234568E2") == 0);
Complex::convertFloatToText(-0.000123456789f, buffer, 14, 7);
assert(strcmp(buffer, "-1.234568E-4") == 0);
Complex::convertFloatToText(0.0f, buffer, 14, 7);
assert(strcmp(buffer, "0.0E0") == 0);
Complex::convertFloatToText(10000000000000000000000000000.0f, buffer, 14, 7);
assert(strcmp(buffer, "1.0E28") == 0);
Complex::convertFloatToText(10000000000000000000000000000.0f, buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E28") == 0);
Complex::convertFloatToText(1000000.0f, buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1000000") == 0);
Complex::convertFloatToText(10000000.0f, buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E7") == 0);
Complex::convertFloatToText(0.000001f, buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "0.000001") == 0);
Complex::convertFloatToText(0.0000001f, buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E-7") == 0);
char buffer2[6];
Complex::convertFloatToText(123.421f, buffer2, 6, 4, Expression::DisplayMode::Auto);
assert(strcmp(buffer2, "123.4") == 0);
char buffer3[6];
Complex::convertFloatToText(123.421f, buffer3, 6, 5, Expression::DisplayMode::Auto);
assert(strcmp(buffer3, "1.2E2") == 0);
}
QUIZ_CASE(poincare_complex_approximate) {
GlobalContext globalContext;
Expression * a = new Complex(123.456f);
assert(a->approximate(globalContext) == 123.456f);
delete a;
}
QUIZ_CASE(poincare_complex_evaluate) {
GlobalContext globalContext;
Expression * a = new Complex(123.456f);
Expression * e = a->evaluate(globalContext);
assert(e->approximate(globalContext) == 123.456f);
delete a;
delete e;
}

View File

@@ -1,60 +0,0 @@
#include <quiz.h>
#include <poincare.h>
#include <string.h>
#include <assert.h>
QUIZ_CASE(poincare_float_to_text) {
char buffer [14];
Float(123.456f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "1.23456E2") == 0);
Float(1.234567891011f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "1.234568E0") == 0);
Float(2.0f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "2.0E0") == 0);
Float(123456789.0f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "1.234568E8") == 0);
Float(0.00000123456789f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "1.234568E-6") == 0);
Float(0.99f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "9.9E-1") == 0);
Float(-123.456789f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "-1.234568E2") == 0);
Float(-0.000123456789f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "-1.234568E-4") == 0);
Float(0.0f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "0.0E0") == 0);
Float(10000000000000000000000000000.0f).convertFloatToText(buffer, 14, 7);
assert(strcmp(buffer, "1.0E28") == 0);
Float(10000000000000000000000000000.0f).convertFloatToText(buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E28") == 0);
Float(1000000.0f).convertFloatToText(buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1000000") == 0);
Float(10000000.0f).convertFloatToText(buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E7") == 0);
Float(0.000001f).convertFloatToText(buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "0.000001") == 0);
Float(0.0000001f).convertFloatToText(buffer, 14, 7, Expression::DisplayMode::Auto);
assert(strcmp(buffer, "1.0E-7") == 0);
char buffer2[6];
Float(123.421f).convertFloatToText(buffer2, 6, 4, Expression::DisplayMode::Auto);
assert(strcmp(buffer2, "123.4") == 0);
char buffer3[6];
Float(123.421f).convertFloatToText(buffer3, 6, 5, Expression::DisplayMode::Auto);
assert(strcmp(buffer3, "1.2E2") == 0);
}
QUIZ_CASE(poincare_float_approximate) {
GlobalContext globalContext;
Expression * a = new Float(123.456f);
assert(a->approximate(globalContext) == 123.456f);
delete a;
}
QUIZ_CASE(poincare_float_evaluate) {
GlobalContext globalContext;
Expression * a = new Float(123.456f);
Expression * e = a->evaluate(globalContext);
assert(e->approximate(globalContext) == 123.456f);
delete a;
delete e;
}