mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare] PrintFloat: take into account the distinction between char
and glyph length in ConvertFloatToText
This commit is contained in:
committed by
LeaNumworks
parent
d6ad694b76
commit
4d593a6149
@@ -43,7 +43,7 @@ bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCurso
|
|||||||
|
|
||||||
void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) {
|
void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) {
|
||||||
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(record);
|
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(record);
|
||||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
const char * space = " ";
|
const char * space = " ";
|
||||||
int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize);
|
int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const char * IntersectionGraphController::title() {
|
|||||||
|
|
||||||
void IntersectionGraphController::reloadBannerView() {
|
void IntersectionGraphController::reloadBannerView() {
|
||||||
CalculationGraphController::reloadBannerView();
|
CalculationGraphController::reloadBannerView();
|
||||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits);
|
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+Poincare::PrintFloat::charSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
const char * space = " ";
|
const char * space = " ";
|
||||||
const char * legend = "=";
|
const char * legend = "=";
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ void TangentGraphController::reloadBannerView() {
|
|||||||
}
|
}
|
||||||
FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, Shared::FunctionApp::app()->functionStore(), AppsContainer::sharedAppsContainer()->globalContext());
|
FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, Shared::FunctionApp::app()->functionStore(), AppsContainer::sharedAppsContainer()->globalContext());
|
||||||
GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record);
|
GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record);
|
||||||
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters + PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
Poincare::Context * context = textFieldDelegateApp()->localContext();
|
Poincare::Context * context = textFieldDelegateApp()->localContext();
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ void TangentGraphController::reloadBannerView() {
|
|||||||
int legendLength = strlcpy(buffer, legend, bufferSize);
|
int legendLength = strlcpy(buffer, legend, bufferSize);
|
||||||
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_record);
|
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_record);
|
||||||
double y = function->approximateDerivative(m_cursor->x(), context);
|
double y = function->approximateDerivative(m_cursor->x(), context);
|
||||||
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision);
|
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, bufferSize - legendLength, precision);
|
||||||
m_bannerView->aView()->setText(buffer);
|
m_bannerView->aView()->setText(buffer);
|
||||||
|
|
||||||
legend = "b=";
|
legend = "b=";
|
||||||
@@ -84,7 +84,7 @@ void TangentGraphController::reloadBannerView() {
|
|||||||
Shared::TextFieldDelegateApp * myApp = textFieldDelegateApp();
|
Shared::TextFieldDelegateApp * myApp = textFieldDelegateApp();
|
||||||
assert(function->plotType() == Shared::ContinuousFunction::PlotType::Cartesian);
|
assert(function->plotType() == Shared::ContinuousFunction::PlotType::Cartesian);
|
||||||
y = -y*m_cursor->x()+function->evaluate2DAtParameter(m_cursor->x(), myApp->localContext()).x2();
|
y = -y*m_cursor->x()+function->evaluate2DAtParameter(m_cursor->x(), myApp->localContext()).x2();
|
||||||
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision);
|
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, bufferSize - legendLength, precision);
|
||||||
m_bannerView->bView()->setText(buffer);
|
m_bannerView->bView()->setText(buffer);
|
||||||
m_bannerView->reload();
|
m_bannerView->reload();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,21 +53,22 @@ char intervalBracket(double value, bool opening) {
|
|||||||
return std::isinf(value) == opening ? ']' : '[';
|
return std::isinf(value) == opening ? ']' : '[';
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeInterval(char * buffer, int bufferSize, double min, double max, int numberOfSignificantDigits, Preferences::PrintFloatMode mode) {
|
int writeInterval(char * buffer, int bufferSize, double min, double max, int numberOfSignificantDigits, Preferences::PrintFloatMode mode) {
|
||||||
int numberOfChar = 0;
|
int numberOfChar = 0;
|
||||||
assert(bufferSize-1 > numberOfChar);
|
assert(bufferSize-1 > numberOfChar);
|
||||||
buffer[numberOfChar++] = intervalBracket(min, true);
|
buffer[numberOfChar++] = intervalBracket(min, true);
|
||||||
int sizeRequiredForFloat = PrintFloat::bufferSizeForFloatsWithPrecision(numberOfSignificantDigits);
|
int glyphLengthRequiredForFloat = PrintFloat::glyphLengthForFloatWithPrecision(numberOfSignificantDigits);
|
||||||
assert(sizeRequiredForFloat < bufferSize - numberOfChar);
|
PrintFloat::TextLengths minLengths = PrintFloat::ConvertFloatToText<double>(min, buffer+numberOfChar, bufferSize - numberOfChar, glyphLengthRequiredForFloat, numberOfSignificantDigits, mode);
|
||||||
numberOfChar += PrintFloat::ConvertFloatToText<double>(min, buffer+numberOfChar, sizeRequiredForFloat, numberOfSignificantDigits, mode);
|
numberOfChar += minLengths.CharLength;
|
||||||
assert(bufferSize > numberOfChar);
|
assert(bufferSize > numberOfChar);
|
||||||
numberOfChar += strlcpy(buffer+numberOfChar, ",", bufferSize-numberOfChar);
|
numberOfChar += strlcpy(buffer+numberOfChar, ",", bufferSize-numberOfChar);
|
||||||
assert(sizeRequiredForFloat < bufferSize - numberOfChar);
|
PrintFloat::TextLengths maxLengths = PrintFloat::ConvertFloatToText<double>(max, buffer+numberOfChar, bufferSize - numberOfChar, glyphLengthRequiredForFloat, numberOfSignificantDigits, mode);
|
||||||
numberOfChar += PrintFloat::ConvertFloatToText<double>(max, buffer+numberOfChar, sizeRequiredForFloat, numberOfSignificantDigits, mode);
|
numberOfChar += maxLengths.CharLength;
|
||||||
assert(bufferSize-1 > numberOfChar);
|
assert(bufferSize-1 > numberOfChar);
|
||||||
buffer[numberOfChar++] = intervalBracket(max, false);
|
buffer[numberOfChar++] = intervalBracket(max, false);
|
||||||
assert(bufferSize > numberOfChar);
|
assert(bufferSize > numberOfChar);
|
||||||
strlcpy(buffer+numberOfChar, " ", bufferSize-numberOfChar);
|
strlcpy(buffer+numberOfChar, " ", bufferSize-numberOfChar);
|
||||||
|
return minLengths.GlyphLength + maxLengths. GlyphLength + 3 + 1; // Count "[,] " glyphs
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
void ListParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
|
||||||
@@ -87,9 +88,9 @@ void ListParameterController::willDisplayCellForIndex(HighlightCell * cell, int
|
|||||||
double max = function->tMax();
|
double max = function->tMax();
|
||||||
constexpr int bufferSize = BufferTextView::k_maxNumberOfChar;
|
constexpr int bufferSize = BufferTextView::k_maxNumberOfChar;
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
writeInterval(buffer, bufferSize, min, max, Preferences::VeryShortNumberOfSignificantDigits, Preferences::sharedPreferences()->displayMode());
|
int glyphLength = writeInterval(buffer, bufferSize, min, max, Preferences::VeryShortNumberOfSignificantDigits, Preferences::sharedPreferences()->displayMode());
|
||||||
int numberOfAvailableChar = (m_functionDomain.bounds().width() - m_functionDomain.labelView()->bounds().width() - m_functionDomain.accessoryView()->bounds().width() - TableCell::k_labelMargin - TableCell::k_accessoryMargin)/KDFont::SmallFont->glyphSize().width();
|
int numberOfAvailableGlyphs = (m_functionDomain.bounds().width() - m_functionDomain.labelView()->bounds().width() - m_functionDomain.accessoryView()->bounds().width() - TableCell::k_labelMargin - TableCell::k_accessoryMargin)/KDFont::SmallFont->glyphSize().width();
|
||||||
if (UTF8Helper::StringGlyphLength(buffer) > numberOfAvailableChar) {
|
if (glyphLength > numberOfAvailableGlyphs) {
|
||||||
writeInterval(buffer, bufferSize, min, max, Preferences::VeryShortNumberOfSignificantDigits-1, Preferences::PrintFloatMode::Scientific);
|
writeInterval(buffer, bufferSize, min, max, Preferences::VeryShortNumberOfSignificantDigits-1, Preferences::PrintFloatMode::Scientific);
|
||||||
}
|
}
|
||||||
m_functionDomain.setAccessoryText(buffer);
|
m_functionDomain.setAccessoryText(buffer);
|
||||||
|
|||||||
@@ -248,17 +248,14 @@ void ValuesController::printEvaluationOfAbscissaAtColumn(double abscissa, int co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int numberOfChar = 0;
|
int numberOfChar = 0;
|
||||||
const int floatBufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
|
||||||
if (isParametric) {
|
if (isParametric) {
|
||||||
assert(numberOfChar < bufferSize-1);
|
assert(numberOfChar < bufferSize-1);
|
||||||
buffer[numberOfChar++] = '(';
|
buffer[numberOfChar++] = '(';
|
||||||
assert(floatBufferSize <= bufferSize-numberOfChar);
|
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(evaluationX, buffer+numberOfChar, bufferSize - numberOfChar, Preferences::LargeNumberOfSignificantDigits);
|
||||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(evaluationX, buffer+numberOfChar, floatBufferSize, Preferences::LargeNumberOfSignificantDigits);
|
|
||||||
assert(numberOfChar < bufferSize-1);
|
assert(numberOfChar < bufferSize-1);
|
||||||
buffer[numberOfChar++] = ';';
|
buffer[numberOfChar++] = ';';
|
||||||
}
|
}
|
||||||
assert(floatBufferSize <= bufferSize-numberOfChar);
|
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(evaluationY, buffer+numberOfChar, bufferSize - numberOfChar, Preferences::LargeNumberOfSignificantDigits);
|
||||||
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(evaluationY, buffer+numberOfChar, floatBufferSize, Preferences::LargeNumberOfSignificantDigits);
|
|
||||||
if (isParametric) {
|
if (isParametric) {
|
||||||
assert(numberOfChar+1 < bufferSize-1);
|
assert(numberOfChar+1 < bufferSize-1);
|
||||||
buffer[numberOfChar++] = ')';
|
buffer[numberOfChar++] = ')';
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "battery_test_controller.h"
|
#include "battery_test_controller.h"
|
||||||
#include <apps/shared/post_and_hardware_tests.h>
|
#include <apps/shared/post_and_hardware_tests.h>
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
#include <apps/shared/poincare_helpers.h>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
}
|
}
|
||||||
@@ -8,6 +9,7 @@ extern "C" {
|
|||||||
#include <poincare/preferences.h>
|
#include <poincare/preferences.h>
|
||||||
|
|
||||||
using namespace Poincare;
|
using namespace Poincare;
|
||||||
|
using namespace Shared;
|
||||||
|
|
||||||
namespace HardwareTest {
|
namespace HardwareTest {
|
||||||
|
|
||||||
@@ -43,12 +45,12 @@ void BatteryTestController::viewWillAppear() {
|
|||||||
|
|
||||||
void BatteryTestController::updateBatteryState(float batteryLevel, bool batteryCharging) {
|
void BatteryTestController::updateBatteryState(float batteryLevel, bool batteryCharging) {
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int sizeForPrecision = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int sizeForPrecision = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
constexpr size_t bufferLevelSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision;
|
constexpr size_t bufferLevelSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision;
|
||||||
char bufferLevel[bufferLevelSize];
|
char bufferLevel[bufferLevelSize];
|
||||||
const char * legend = "Battery level: ";
|
const char * legend = "Battery level: ";
|
||||||
int legendLength = strlcpy(bufferLevel, legend, bufferLevelSize);
|
int legendLength = strlcpy(bufferLevel, legend, bufferLevelSize);
|
||||||
PrintFloat::ConvertFloatToText<float>(batteryLevel, bufferLevel+legendLength, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<float>(batteryLevel, bufferLevel+legendLength, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
m_view.batteryLevelTextView()->setText(bufferLevel);
|
m_view.batteryLevelTextView()->setText(bufferLevel);
|
||||||
|
|
||||||
constexpr size_t bufferChargingSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision;
|
constexpr size_t bufferChargingSize = ContentView::k_maxNumberOfCharacters + sizeForPrecision;
|
||||||
|
|||||||
@@ -180,9 +180,10 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<double>(m_calculation->parameterAtIndex(i-1), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
// FIXME: Leo has not decided yet if we should use the prefered mode instead of always using scientific mode
|
||||||
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(m_calculation->parameterAtIndex(i-1), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
field->setText(buffer);
|
field->setText(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,9 +284,9 @@ void CalculationController::updateTitle() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
constexpr int precision = Preferences::ShortNumberOfSignificantDigits;
|
constexpr int precision = Preferences::ShortNumberOfSignificantDigits;
|
||||||
constexpr size_t bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<double>(m_distribution->parameterValueAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(m_distribution->parameterValueAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
currentChar += strlcpy(m_titleBuffer+currentChar, buffer, k_titleBufferSize - currentChar);
|
currentChar += strlcpy(m_titleBuffer+currentChar, buffer, k_titleBufferSize - currentChar);
|
||||||
if (currentChar >= k_titleBufferSize) {
|
if (currentChar >= k_titleBufferSize) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
double calculation1 = (m_store->*calculationMethods[j-1])(seriesNumber, 0);
|
double calculation1 = (m_store->*calculationMethods[j-1])(seriesNumber, 0);
|
||||||
double calculation2 = (m_store->*calculationMethods[j-1])(seriesNumber, 1);
|
double calculation2 = (m_store->*calculationMethods[j-1])(seriesNumber, 1);
|
||||||
EvenOddDoubleBufferTextCellWithSeparator * myCell = (EvenOddDoubleBufferTextCellWithSeparator *)cell;
|
EvenOddDoubleBufferTextCellWithSeparator * myCell = (EvenOddDoubleBufferTextCellWithSeparator *)cell;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(numberSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(calculation1, buffer, bufferSize, numberSignificantDigits);
|
PoincareHelpers::ConvertFloatToText<double>(calculation1, buffer, bufferSize, numberSignificantDigits);
|
||||||
myCell->setFirstText(buffer);
|
myCell->setFirstText(buffer);
|
||||||
@@ -198,7 +198,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
assert(j != k_regressionCellIndex);
|
assert(j != k_regressionCellIndex);
|
||||||
CalculPointer calculationMethods[] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance, &Store::columnProductSum};
|
CalculPointer calculationMethods[] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance, &Store::columnProductSum};
|
||||||
double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])(seriesNumber);
|
double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])(seriesNumber);
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(numberSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, numberSignificantDigits);
|
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, numberSignificantDigits);
|
||||||
bufferCell->setText(buffer);
|
bufferCell->setText(buffer);
|
||||||
@@ -230,7 +230,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
if (modelType == Model::Type::Linear) {
|
if (modelType == Model::Type::Linear) {
|
||||||
CalculPointer calculationMethods[2] = {&Store::correlationCoefficient, &Store::squaredCorrelationCoefficient};
|
CalculPointer calculationMethods[2] = {&Store::correlationCoefficient, &Store::squaredCorrelationCoefficient};
|
||||||
double calculation = (m_store->*calculationMethods[j - k_regressionCellIndex - maxNumberCoefficients - 1])(seriesNumber);
|
double calculation = (m_store->*calculationMethods[j - k_regressionCellIndex - maxNumberCoefficients - 1])(seriesNumber);
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(numberSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, numberSignificantDigits);
|
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, numberSignificantDigits);
|
||||||
bufferCell->setText(buffer);
|
bufferCell->setText(buffer);
|
||||||
@@ -246,7 +246,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
bufferCell->setText(I18n::translate(I18n::Message::Dash));
|
bufferCell->setText(I18n::translate(I18n::Message::Dash));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(numberSignificantDigits);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(numberSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(coefficients[j - k_regressionCellIndex - 1], buffer, bufferSize, numberSignificantDigits);
|
PoincareHelpers::ConvertFloatToText<double>(coefficients[j - k_regressionCellIndex - 1], buffer, bufferSize, numberSignificantDigits);
|
||||||
bufferCell->setText(buffer);
|
bufferCell->setText(buffer);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ private:
|
|||||||
static constexpr KDCoordinate k_cellHeight = 25;
|
static constexpr KDCoordinate k_cellHeight = 25;
|
||||||
static constexpr KDCoordinate k_titleCalculationCellWidth = Ion::Display::Width/2 - Metric::CommonRightMargin/2 - Metric::CommonLeftMargin/2;
|
static constexpr KDCoordinate k_titleCalculationCellWidth = Ion::Display::Width/2 - Metric::CommonRightMargin/2 - Metric::CommonLeftMargin/2;
|
||||||
// TODO: change 7 for KDFont::SmallFont->glyphSize().width()
|
// TODO: change 7 for KDFont::SmallFont->glyphSize().width()
|
||||||
static constexpr KDCoordinate k_minCalculationCellWidth = 7*2*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits)); //Calculation width should at least be able to hold to numbers with LargeNumberOfSignificantDigits.
|
static constexpr KDCoordinate k_minCalculationCellWidth = 7*2*(Poincare::PrintFloat::glyphLengthForFloatWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits)); //Calculation width should at least be able to hold to numbers with LargeNumberOfSignificantDigits.
|
||||||
static constexpr KDCoordinate k_cubicCalculationCellWidth = maxCoordinate(150, k_minCalculationCellWidth); // Should hold aX^3+bX^2+cX+d
|
static constexpr KDCoordinate k_cubicCalculationCellWidth = maxCoordinate(150, k_minCalculationCellWidth); // Should hold aX^3+bX^2+cX+d
|
||||||
static constexpr KDCoordinate k_quarticCalculationCellWidth = maxCoordinate(195, k_minCalculationCellWidth ); // Should hold ? aX^4+bX^3+c*X^2+dX+e
|
static constexpr KDCoordinate k_quarticCalculationCellWidth = maxCoordinate(195, k_minCalculationCellWidth ); // Should hold ? aX^4+bX^3+c*X^2+dX+e
|
||||||
static constexpr KDCoordinate k_margin = 8;
|
static constexpr KDCoordinate k_margin = 8;
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ Poincare::Context * GraphController::globalContext() {
|
|||||||
|
|
||||||
void GraphController::reloadBannerView() {
|
void GraphController::reloadBannerView() {
|
||||||
// Set point equals: "P(...) ="
|
// Set point equals: "P(...) ="
|
||||||
constexpr size_t bufferSize = k_maxNumberOfCharacters + PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
constexpr size_t bufferSize = k_maxNumberOfCharacters + PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
int numberOfChar = 0;
|
int numberOfChar = 0;
|
||||||
const char * legend = " P(";
|
const char * legend = " P(";
|
||||||
@@ -119,7 +119,7 @@ void GraphController::reloadBannerView() {
|
|||||||
assert(numberOfChar <= bufferSize);
|
assert(numberOfChar <= bufferSize);
|
||||||
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
|
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
|
||||||
} else {
|
} else {
|
||||||
numberOfChar += PrintFloat::ConvertFloatToText<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Preferences::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
numberOfChar += PoincareHelpers::ConvertFloatToTextWithDisplayMode<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Preferences::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
||||||
}
|
}
|
||||||
legend = ") ";
|
legend = ") ";
|
||||||
assert(numberOfChar <= bufferSize);
|
assert(numberOfChar <= bufferSize);
|
||||||
|
|||||||
@@ -73,9 +73,7 @@ bool ValuesController::setDataAtLocation(double floatBody, int columnIndex, int
|
|||||||
void ValuesController::printEvaluationOfAbscissaAtColumn(double abscissa, int columnIndex, char * buffer, const int bufferSize) {
|
void ValuesController::printEvaluationOfAbscissaAtColumn(double abscissa, int columnIndex, char * buffer, const int bufferSize) {
|
||||||
Shared::ExpiringPointer<Sequence> sequence = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
Shared::ExpiringPointer<Sequence> sequence = functionStore()->modelForRecord(recordAtColumn(columnIndex));
|
||||||
Coordinate2D<double> xy = sequence->evaluateXYAtParameter(abscissa, textFieldDelegateApp()->localContext());
|
Coordinate2D<double> xy = sequence->evaluateXYAtParameter(abscissa, textFieldDelegateApp()->localContext());
|
||||||
const int floatBufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
Shared::PoincareHelpers::ConvertFloatToText<double>(xy.x2(), buffer, bufferSize, Preferences::LargeNumberOfSignificantDigits);
|
||||||
assert(floatBufferSize <= bufferSize);
|
|
||||||
Shared::PoincareHelpers::ConvertFloatToText<double>(xy.x2(), buffer, floatBufferSize, Preferences::LargeNumberOfSignificantDigits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shared::Interval * ValuesController::intervalAtColumn(int columnIndex) {
|
Shared::Interval * ValuesController::intervalAtColumn(int columnIndex) {
|
||||||
|
|||||||
@@ -177,10 +177,10 @@ void CurveView::computeLabels(Axis axis) {
|
|||||||
float labelValue = labelValueAtIndex(axis, i);
|
float labelValue = labelValueAtIndex(axis, i);
|
||||||
/* Label cannot hold more than k_labelBufferMaxSize characters to prevent
|
/* Label cannot hold more than k_labelBufferMaxSize characters to prevent
|
||||||
* them from overprinting one another.*/
|
* them from overprinting one another.*/
|
||||||
int labelMaxSize = k_labelBufferMaxSize;
|
int labelMaxGlyphLength = k_labelBufferMaxGlyphLength;
|
||||||
if (axis == Axis::Horizontal) {
|
if (axis == Axis::Horizontal) {
|
||||||
float pixelsPerLabel = maxFloat(0.0f, ((float)Ion::Display::Width)/((float)axisLabelsCount) - k_labelMargin);
|
float pixelsPerLabel = maxFloat(0.0f, ((float)Ion::Display::Width)/((float)axisLabelsCount) - k_labelMargin);
|
||||||
labelMaxSize = minInt(k_labelBufferMaxSize, pixelsPerLabel/k_font->glyphSize().width()+1);
|
labelMaxGlyphLength = minInt(k_labelBufferMaxGlyphLength, pixelsPerLabel/k_font->glyphSize().width());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labelValue < step && labelValue > -step) {
|
if (labelValue < step && labelValue > -step) {
|
||||||
@@ -195,7 +195,8 @@ void CurveView::computeLabels(Axis axis) {
|
|||||||
PrintFloat::ConvertFloatToText<float>(
|
PrintFloat::ConvertFloatToText<float>(
|
||||||
labelValue,
|
labelValue,
|
||||||
labelBuffer,
|
labelBuffer,
|
||||||
labelMaxSize,
|
k_labelBufferMaxSize,
|
||||||
|
labelMaxGlyphLength,
|
||||||
k_numberSignificantDigits,
|
k_numberSignificantDigits,
|
||||||
Preferences::PrintFloatMode::Decimal);
|
Preferences::PrintFloatMode::Decimal);
|
||||||
|
|
||||||
@@ -825,6 +826,7 @@ void CurveView::computeHorizontalExtremaLabels(bool increaseNumberOfSignificantD
|
|||||||
labelValueAtIndex(axis, i),
|
labelValueAtIndex(axis, i),
|
||||||
label(axis, i),
|
label(axis, i),
|
||||||
k_labelBufferMaxSize,
|
k_labelBufferMaxSize,
|
||||||
|
k_labelBufferMaxGlyphLength,
|
||||||
increaseNumberOfSignificantDigits ? k_bigNumberSignificantDigits : k_numberSignificantDigits,
|
increaseNumberOfSignificantDigits ? k_bigNumberSignificantDigits : k_numberSignificantDigits,
|
||||||
Preferences::PrintFloatMode::Decimal);
|
Preferences::PrintFloatMode::Decimal);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ protected:
|
|||||||
constexpr static KDCoordinate k_labelGraduationLength = 6;
|
constexpr static KDCoordinate k_labelGraduationLength = 6;
|
||||||
constexpr static int k_numberSignificantDigits = 6;
|
constexpr static int k_numberSignificantDigits = 6;
|
||||||
constexpr static int k_bigNumberSignificantDigits = Poincare::Preferences::LargeNumberOfSignificantDigits;
|
constexpr static int k_bigNumberSignificantDigits = Poincare::Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr static int k_labelBufferMaxSize = 1 + k_bigNumberSignificantDigits + 3 + 3 + 1; // '-' + significant digits + '.' + "E-" + 3 digits + null-terminating char
|
constexpr static int k_labelBufferMaxSize = 1 + k_bigNumberSignificantDigits + 1 + Poincare::PrintFloat::k_specialECodePointByteLength + 1 + 3 + 1; // '-' + significant digits + '.' + "E" + '-' + 3 digits + null-terminating char
|
||||||
|
constexpr static int k_labelBufferMaxGlyphLength = 1 + k_bigNumberSignificantDigits + 3 + 3; // '-' + significant digits + ".E-" + 3 digits
|
||||||
constexpr static int k_maxNumberOfXLabels = CurveViewRange::k_maxNumberOfXGridUnits;
|
constexpr static int k_maxNumberOfXLabels = CurveViewRange::k_maxNumberOfXGridUnits;
|
||||||
constexpr static int k_maxNumberOfYLabels = CurveViewRange::k_maxNumberOfYGridUnits;
|
constexpr static int k_maxNumberOfYLabels = CurveViewRange::k_maxNumberOfYGridUnits;
|
||||||
constexpr static int k_externRectMargin = 2;
|
constexpr static int k_externRectMargin = 2;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(H
|
|||||||
if (cellAtLocationIsEditable(i, j)) {
|
if (cellAtLocationIsEditable(i, j)) {
|
||||||
EvenOddEditableTextCell * myEditableValueCell = (EvenOddEditableTextCell *)cell;
|
EvenOddEditableTextCell * myEditableValueCell = (EvenOddEditableTextCell *)cell;
|
||||||
assert(!myEditableValueCell->editableTextCell()->textField()->isEditing());
|
assert(!myEditableValueCell->editableTextCell()->textField()->isEditing());
|
||||||
const int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
const int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
// Special case 1: last row
|
// Special case 1: last row
|
||||||
if (j == numberOfElementsInColumn(i) + 1) {
|
if (j == numberOfElementsInColumn(i) + 1) {
|
||||||
@@ -86,7 +86,7 @@ void EditableCellTableViewController::willDisplayCellAtLocationWithDisplayMode(H
|
|||||||
* data */
|
* data */
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
} else {
|
} else {
|
||||||
PrintFloat::ConvertFloatToText<double>(dataAtLocation(i, j), buffer, bufferSize, Preferences::LargeNumberOfSignificantDigits, floatDisplayMode);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(dataAtLocation(i, j), buffer, bufferSize, Preferences::LargeNumberOfSignificantDigits, floatDisplayMode);
|
||||||
}
|
}
|
||||||
myEditableValueCell->editableTextCell()->textField()->setText(buffer);
|
myEditableValueCell->editableTextCell()->textField()->setText(buffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,9 +121,9 @@ void FloatParameterController<T>::willDisplayCellForIndex(HighlightCell * cell,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<T>(parameterAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<T>(parameterAtIndex(index), buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
myCell->setAccessoryText(buffer);
|
myCell->setAccessoryText(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace Shared {
|
|||||||
|
|
||||||
void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, FunctionStore * functionStore, Poincare::Context * context) {
|
void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Ion::Storage::Record record, FunctionStore * functionStore, Poincare::Context * context) {
|
||||||
ExpiringPointer<Function> function = functionStore->modelForRecord(record);
|
ExpiringPointer<Function> function = functionStore->modelForRecord(record);
|
||||||
constexpr int bufferSize = k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
constexpr int bufferSize = k_maxNumberOfCharacters+PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
const char * space = " ";
|
const char * space = " ";
|
||||||
int numberOfChar = 0;
|
int numberOfChar = 0;
|
||||||
@@ -20,7 +20,7 @@ void FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(CurveViewCursor
|
|||||||
|
|
||||||
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
||||||
|
|
||||||
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(cursor->t(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(precision), precision);
|
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(cursor->t(), buffer, bufferSize, precision);
|
||||||
assert(numberOfChar <= bufferSize);
|
assert(numberOfChar <= bufferSize);
|
||||||
strlcpy(buffer+numberOfChar, space, bufferSize - numberOfChar);
|
strlcpy(buffer+numberOfChar, space, bufferSize - numberOfChar);
|
||||||
bannerView()->abscissaValue()->setText(buffer);
|
bannerView()->abscissaValue()->setText(buffer);
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ inline Poincare::Layout CreateLayout(const Poincare::Expression e) {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline int ConvertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits) {
|
inline int ConvertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits) {
|
||||||
return Poincare::PrintFloat::ConvertFloatToText(d, buffer, bufferSize, numberOfSignificantDigits, Poincare::Preferences::sharedPreferences()->displayMode());
|
return Poincare::PrintFloat::ConvertFloatToText(d, buffer, bufferSize, Poincare::PrintFloat::glyphLengthForFloatWithPrecision(numberOfSignificantDigits), numberOfSignificantDigits, Poincare::Preferences::sharedPreferences()->displayMode()).CharLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline int ConvertFloatToTextWithDisplayMode(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Poincare::Preferences::PrintFloatMode displayMode) {
|
||||||
|
return Poincare::PrintFloat::ConvertFloatToText(d, buffer, bufferSize, Poincare::PrintFloat::glyphLengthForFloatWithPrecision(numberOfSignificantDigits), numberOfSignificantDigits, displayMode).CharLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Serialize(const Poincare::Expression e, char * buffer, int bufferSize, int numberOfSignificantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits) {
|
inline int Serialize(const Poincare::Expression e, char * buffer, int bufferSize, int numberOfSignificantDigits = Poincare::PrintFloat::k_numberOfStoredSignificantDigits) {
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ void SumGraphController::LegendView::setLegendMessage(I18n::Message message, Ste
|
|||||||
|
|
||||||
void SumGraphController::LegendView::setEditableZone(double d) {
|
void SumGraphController::LegendView::setEditableZone(double d) {
|
||||||
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<double>(d, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(d, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
m_editableZone.setText(buffer);
|
m_editableZone.setText(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,28 +193,28 @@ void SumGraphController::LegendView::setSumSymbol(Step step, double start, doubl
|
|||||||
m_sumLayout = LayoutHelper::CodePointString(sigma, sigmaLength);
|
m_sumLayout = LayoutHelper::CodePointString(sigma, sigmaLength);
|
||||||
} else if (step == Step::SecondParameter) {
|
} else if (step == Step::SecondParameter) {
|
||||||
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<double>(start, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(start, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
m_sumLayout = CondensedSumLayout::Builder(
|
m_sumLayout = CondensedSumLayout::Builder(
|
||||||
LayoutHelper::CodePointString(sigma, sigmaLength),
|
LayoutHelper::CodePointString(sigma, sigmaLength),
|
||||||
LayoutHelper::String(buffer, strlen(buffer), k_font),
|
LayoutHelper::String(buffer, strlen(buffer), k_font),
|
||||||
EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow, false, k_font, false));
|
EmptyLayout::Builder(EmptyLayoutNode::Color::Yellow, false, k_font, false));
|
||||||
} else {
|
} else {
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int sizeForPrecision = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int sizeForPrecision = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
constexpr int bufferSize = 2 + sizeForPrecision;
|
constexpr int bufferSize = 2 + sizeForPrecision;
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PrintFloat::ConvertFloatToText<double>(start, buffer, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(start, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
Layout start = LayoutHelper::String(buffer, strlen(buffer), k_font);
|
Layout start = LayoutHelper::String(buffer, strlen(buffer), k_font);
|
||||||
PrintFloat::ConvertFloatToText<double>(end, buffer, sizeForPrecision, precision, Preferences::PrintFloatMode::Decimal);
|
PoincareHelpers::ConvertFloatToTextWithDisplayMode<double>(end, buffer, bufferSize, precision, Preferences::PrintFloatMode::Decimal);
|
||||||
Layout end = LayoutHelper::String(buffer, strlen(buffer), k_font);
|
Layout end = LayoutHelper::String(buffer, strlen(buffer), k_font);
|
||||||
m_sumLayout = CondensedSumLayout::Builder(
|
m_sumLayout = CondensedSumLayout::Builder(
|
||||||
LayoutHelper::CodePointString(sigma, sigmaLength),
|
LayoutHelper::CodePointString(sigma, sigmaLength),
|
||||||
start,
|
start,
|
||||||
end);
|
end);
|
||||||
strlcpy(buffer, "= ", 3);
|
strlcpy(buffer, "= ", 3);
|
||||||
PoincareHelpers::ConvertFloatToText<double>(result, buffer+2, sizeForPrecision, precision);
|
PoincareHelpers::ConvertFloatToText<double>(result, buffer+2, bufferSize-2, precision);
|
||||||
m_sumLayout = HorizontalLayout::Builder(
|
m_sumLayout = HorizontalLayout::Builder(
|
||||||
m_sumLayout,
|
m_sumLayout,
|
||||||
functionLayout,
|
functionLayout,
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
void setEditableZone(double d);
|
void setEditableZone(double d);
|
||||||
void setSumSymbol(Step step, double start, double end, double result, Poincare::Layout functionLayout);
|
void setSumSymbol(Step step, double start, double end, double result, Poincare::Layout functionLayout);
|
||||||
private:
|
private:
|
||||||
constexpr static KDCoordinate k_editableZoneBufferSize = Poincare::PrintFloat::k_maxFloatBufferSize;
|
constexpr static KDCoordinate k_editableZoneBufferSize = Poincare::PrintFloat::k_maxFloatCharSize;
|
||||||
constexpr static KDCoordinate k_legendHeight = 35;
|
constexpr static KDCoordinate k_legendHeight = 35;
|
||||||
constexpr static const KDFont * k_font = KDFont::SmallFont;
|
constexpr static const KDFont * k_font = KDFont::SmallFont;
|
||||||
static KDCoordinate editableZoneWidth() { return 12*k_font->glyphSize().width(); }
|
static KDCoordinate editableZoneWidth() { return 12*k_font->glyphSize().width(); }
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ void ValuesController::willDisplayCellAtLocation(HighlightCell * cell, int i, in
|
|||||||
willDisplayCellAtLocationWithDisplayMode(cell, i, j, Preferences::sharedPreferences()->displayMode());
|
willDisplayCellAtLocationWithDisplayMode(cell, i, j, Preferences::sharedPreferences()->displayMode());
|
||||||
// The cell is not a title cell and not editable
|
// The cell is not a title cell and not editable
|
||||||
if (typeAtLocation(i,j) == k_notEditableValueCellType) {
|
if (typeAtLocation(i,j) == k_notEditableValueCellType) {
|
||||||
constexpr int bufferSize = 2*PrintFloat::bufferSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits)+3;
|
constexpr int bufferSize = 2*PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits)+3;
|
||||||
char buffer[bufferSize]; // The largest buffer holds (-1.234567E-123;-1.234567E-123)
|
char buffer[bufferSize]; // The largest buffer holds (-1.234567E-123;-1.234567E-123)
|
||||||
// Special case: last row
|
// Special case: last row
|
||||||
if (j == numberOfElementsInColumn(i) + 1) {
|
if (j == numberOfElementsInColumn(i) + 1) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
View * subviewAtIndex(int index) override;
|
View * subviewAtIndex(int index) override;
|
||||||
private:
|
private:
|
||||||
constexpr static KDCoordinate k_abscissaBufferSize = Poincare::PrintFloat::k_maxFloatBufferSize;
|
constexpr static KDCoordinate k_abscissaBufferSize = Poincare::PrintFloat::k_maxFloatCharSize;
|
||||||
int numberOfSubviews() const override { return k_numberOfSubviews; }
|
int numberOfSubviews() const override { return k_numberOfSubviews; }
|
||||||
BufferTextView m_abscissaSymbol;
|
BufferTextView m_abscissaSymbol;
|
||||||
TextField m_abscissaValue;
|
TextField m_abscissaValue;
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ void SolutionsController::willDisplayCellAtLocation(HighlightCell * cell, int i,
|
|||||||
if (m_equationStore->type() == EquationStore::Type::Monovariable) {
|
if (m_equationStore->type() == EquationStore::Type::Monovariable) {
|
||||||
EvenOddBufferTextCell * valueCell = static_cast<EvenOddBufferTextCell *>(cell);
|
EvenOddBufferTextCell * valueCell = static_cast<EvenOddBufferTextCell *>(cell);
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char bufferValue[bufferSize];
|
char bufferValue[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(m_equationStore->approximateSolutionAtIndex(j), bufferValue, bufferSize, precision);
|
PoincareHelpers::ConvertFloatToText<double>(m_equationStore->approximateSolutionAtIndex(j), bufferValue, bufferSize, precision);
|
||||||
valueCell->setText(bufferValue);
|
valueCell->setText(bufferValue);
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ void BoxController::reloadBannerView() {
|
|||||||
// Set calculation result
|
// Set calculation result
|
||||||
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
|
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision) + 1;
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision) + 1;
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
CalculPointer calculationMethods[5] = {&Store::minValue, &Store::firstQuartile, &Store::median, &Store::thirdQuartile,
|
CalculPointer calculationMethods[5] = {&Store::minValue, &Store::firstQuartile, &Store::median, &Store::thirdQuartile,
|
||||||
&Store::maxValue};
|
&Store::maxValue};
|
||||||
double calculation = (m_store->*calculationMethods[selectedQuantile])(selectedSeriesIndex());
|
double calculation = (m_store->*calculationMethods[selectedQuantile])(selectedSeriesIndex());
|
||||||
int numberOfChar = PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize - 1, precision);
|
int numberOfChar = PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, precision);
|
||||||
buffer[numberOfChar++] = ' ';
|
buffer[numberOfChar++] = ' ';
|
||||||
assert(numberOfChar <= bufferSize - 1);
|
assert(numberOfChar <= bufferSize - 1);
|
||||||
buffer[numberOfChar] = 0;
|
buffer[numberOfChar] = 0;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int
|
|||||||
double calculation = (m_store->*calculationMethods[j-1])(seriesIndex);
|
double calculation = (m_store->*calculationMethods[j-1])(seriesIndex);
|
||||||
EvenOddBufferTextCell * calculationCell = static_cast<EvenOddBufferTextCell *>(cell);
|
EvenOddBufferTextCell * calculationCell = static_cast<EvenOddBufferTextCell *>(cell);
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr int bufferSize = PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, precision);
|
PoincareHelpers::ConvertFloatToText<double>(calculation, buffer, bufferSize, precision);
|
||||||
calculationCell->setText(buffer);
|
calculationCell->setText(buffer);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ private:
|
|||||||
static constexpr KDCoordinate k_cellHeight = 20;
|
static constexpr KDCoordinate k_cellHeight = 20;
|
||||||
static constexpr KDCoordinate k_calculationTitleCellWidth = 175;
|
static constexpr KDCoordinate k_calculationTitleCellWidth = 175;
|
||||||
// TODO: change 7 for KDFont::SmallFont->glyphSize().width()
|
// TODO: change 7 for KDFont::SmallFont->glyphSize().width()
|
||||||
static constexpr KDCoordinate k_calculationCellWidth = 7*(Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits));
|
static constexpr KDCoordinate k_calculationCellWidth = 7*(Poincare::PrintFloat::glyphLengthForFloatWithPrecision(Poincare::Preferences::LargeNumberOfSignificantDigits));
|
||||||
static constexpr KDCoordinate k_margin = 8;
|
static constexpr KDCoordinate k_margin = 8;
|
||||||
static constexpr KDCoordinate k_scrollBarMargin = Metric::CommonRightMargin;
|
static constexpr KDCoordinate k_scrollBarMargin = Metric::CommonRightMargin;
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ void HistogramController::reloadBannerView() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
constexpr int precision = Preferences::LargeNumberOfSignificantDigits;
|
||||||
constexpr size_t bufferSize = k_maxNumberOfCharacters + 2 * PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr size_t bufferSize = k_maxNumberOfCharacters + 2 * PrintFloat::charSizeForFloatsWithPrecision(precision);
|
||||||
char buffer[bufferSize] = "";
|
char buffer[bufferSize] = "";
|
||||||
int numberOfChar = 0;
|
int numberOfChar = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
constexpr static KDCoordinate k_separatorThickness = Metric::CellSeparatorThickness;
|
constexpr static KDCoordinate k_separatorThickness = Metric::CellSeparatorThickness;
|
||||||
TextField m_textField;
|
TextField m_textField;
|
||||||
char m_textBody[Poincare::PrintFloat::k_maxFloatBufferSize];
|
char m_textBody[Poincare::PrintFloat::k_maxFloatCharSize];
|
||||||
KDCoordinate m_topMargin;
|
KDCoordinate m_topMargin;
|
||||||
KDCoordinate m_rightMargin;
|
KDCoordinate m_rightMargin;
|
||||||
KDCoordinate m_bottomMargin;
|
KDCoordinate m_bottomMargin;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void layoutSubviews() override;
|
void layoutSubviews() override;
|
||||||
TextField m_textField;
|
TextField m_textField;
|
||||||
char m_textBody[Poincare::PrintFloat::k_maxFloatBufferSize];
|
char m_textBody[Poincare::PrintFloat::k_maxFloatCharSize];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ EditableTextCell::EditableTextCell(Responder * parentResponder, InputEventHandle
|
|||||||
const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) :
|
const KDFont * font, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) :
|
||||||
HighlightCell(),
|
HighlightCell(),
|
||||||
Responder(parentResponder),
|
Responder(parentResponder),
|
||||||
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatBufferSize, TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
|
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatCharSize, TextField::maxBufferSize(), inputEventHandlerDelegate, delegate, font, horizontalAlignment, verticalAlignment, textColor, backgroundColor),
|
||||||
m_topMargin(topMargin),
|
m_topMargin(topMargin),
|
||||||
m_rightMargin(rightMargin),
|
m_rightMargin(rightMargin),
|
||||||
m_bottomMargin(bottomMargin),
|
m_bottomMargin(bottomMargin),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
MessageTableCellWithEditableText::MessageTableCellWithEditableText(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, I18n::Message message) :
|
MessageTableCellWithEditableText::MessageTableCellWithEditableText(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, I18n::Message message) :
|
||||||
Responder(parentResponder),
|
Responder(parentResponder),
|
||||||
MessageTableCell(message),
|
MessageTableCell(message),
|
||||||
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatBufferSize, TextField::maxBufferSize(), inputEventHandlerDelegate, textFieldDelegate, KDFont::LargeFont, 1.0f, 0.5f)
|
m_textField(this, m_textBody, Poincare::PrintFloat::k_maxFloatCharSize, TextField::maxBufferSize(), inputEventHandlerDelegate, textFieldDelegate, KDFont::LargeFont, 1.0f, 0.5f)
|
||||||
{
|
{
|
||||||
m_textBody[0] = '\0';
|
m_textBody[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ void ADC(const char * input) {
|
|||||||
float result = Ion::Battery::voltage();
|
float result = Ion::Battery::voltage();
|
||||||
constexpr int precision = 8;
|
constexpr int precision = 8;
|
||||||
constexpr int bufferSize = Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
constexpr int bufferSize = Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(precision);
|
||||||
|
constexpr int glyphLength = Poincare::PrintFloat::glyphLengthForFloatWithPrecision(precision);
|
||||||
char responseBuffer[bufferSize+4] = {'A', 'D', 'C', '='}; // ADC=
|
char responseBuffer[bufferSize+4] = {'A', 'D', 'C', '='}; // ADC=
|
||||||
Poincare::PrintFloat::ConvertFloatToText<float>(result, responseBuffer+4, bufferSize, precision, Poincare::Preferences::PrintFloatMode::Decimal);
|
Poincare::PrintFloat::ConvertFloatToText<float>(result, responseBuffer+4, bufferSize, glyphLength, precision, Poincare::Preferences::PrintFloatMode::Decimal);
|
||||||
reply(responseBuffer);
|
reply(responseBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,22 @@ public:
|
|||||||
constexpr static int k_numberOfStoredSignificantDigits = 14;
|
constexpr static int k_numberOfStoredSignificantDigits = 14;
|
||||||
// ᴇ and ℯ are 3 bytes long
|
// ᴇ and ℯ are 3 bytes long
|
||||||
constexpr static int k_specialECodePointByteLength = 3;
|
constexpr static int k_specialECodePointByteLength = 3;
|
||||||
/* We here define the buffer size to write the longest float possible.
|
/* We here define the glyph length and the buffer size to write the longest
|
||||||
|
* float possible.
|
||||||
* At maximum, the number has 15 significant digits so, in the worst case it
|
* At maximum, the number has 15 significant digits so, in the worst case it
|
||||||
* has the form -1.99999999999999ᴇ-308 (2+15+3+1+3 char) (the auto mode is
|
* has the form -1.99999999999999ᴇ-308 (2+15+3+1+3 char) (the decimal mode is
|
||||||
* always shorter. */
|
* always shorter. */
|
||||||
constexpr static int k_maxFloatBufferSize = 2+k_numberOfStoredSignificantDigits+k_specialECodePointByteLength+1+3+1;
|
constexpr static int k_maxFloatGlyphLength = 2 // '-' and '.'
|
||||||
|
+ k_numberOfStoredSignificantDigits // mantissa
|
||||||
|
+ 1 // ᴇ
|
||||||
|
+ 1 // exponant '-'
|
||||||
|
+ 3; // exponant
|
||||||
|
constexpr static int k_maxFloatCharSize = 2 // '-' and '.'
|
||||||
|
+ k_numberOfStoredSignificantDigits // mantissa
|
||||||
|
+ k_specialECodePointByteLength // ᴇ
|
||||||
|
+ 1 // exponant '-'
|
||||||
|
+ 3 // exponant
|
||||||
|
+ 1; // null-terminated
|
||||||
|
|
||||||
constexpr static int glyphLengthForFloatWithPrecision(int numberOfSignificantDigits) {
|
constexpr static int glyphLengthForFloatWithPrecision(int numberOfSignificantDigits) {
|
||||||
// The worst case is -1.234ᴇ-328
|
// The worst case is -1.234ᴇ-328
|
||||||
@@ -27,23 +38,28 @@ public:
|
|||||||
+ 1 // '-'
|
+ 1 // '-'
|
||||||
+ 3; // exponant
|
+ 3; // exponant
|
||||||
}
|
}
|
||||||
constexpr static int bufferSizeForFloatsWithPrecision(int numberOfSignificantDigits) {
|
constexpr static int charSizeForFloatsWithPrecision(int numberOfSignificantDigits) {
|
||||||
// The worst case is -1.234ᴇ-328
|
// The worst case is -1.234ᴇ-328
|
||||||
return 2 // '-' and '.'
|
return 2 // '-' and '.'
|
||||||
+ numberOfSignificantDigits // mantissa
|
+ numberOfSignificantDigits // mantissa
|
||||||
+ k_specialECodePointByteLength // ᴇ
|
+ k_specialECodePointByteLength // ᴇ
|
||||||
+ 1 // '-'
|
+ 1 // exponant '-'
|
||||||
+ 3 // exponant
|
+ 3 // exponant
|
||||||
+ 1; // null-terminated buffer
|
+ 1; // null-terminated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TextLengths
|
||||||
|
{
|
||||||
|
int CharLength;
|
||||||
|
int GlyphLength;
|
||||||
|
};
|
||||||
/* If the buffer size is too small to display the right number of significant
|
/* If the buffer size is too small to display the right number of significant
|
||||||
* digits, the function forces the scientific mode. If the buffer is still too
|
* digits, the function forces the scientific mode. If the buffer is still too
|
||||||
* small, the text representing the float is empty.
|
* small, the text representing the float is empty.
|
||||||
* ConvertFloatToText returns the number of characters that have been written
|
* ConvertFloatToText returns the number of characters that have been written
|
||||||
* in buffer (excluding the last \0 character). */
|
* in buffer (excluding the last \0 character). */
|
||||||
template <class T>
|
template <class T>
|
||||||
static int ConvertFloatToText(T d, char * buffer, int bufferSize, int numberOfSignificantDigits, Preferences::PrintFloatMode mode);
|
static TextLengths ConvertFloatToText(T d, char * buffer, int bufferSize, int availableGlyphLength, int numberOfSignificantDigits, Preferences::PrintFloatMode mode);
|
||||||
|
|
||||||
// Engineering notation
|
// Engineering notation
|
||||||
static int EngineeringExponentFromBase10Exponent(int exponent);
|
static int EngineeringExponentFromBase10Exponent(int exponent);
|
||||||
@@ -59,7 +75,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
template <class T>
|
template <class T>
|
||||||
static int ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, int numberOfSignificantDigits, Preferences::PrintFloatMode mode, int * numberOfRemovedZeros);
|
static TextLengths ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, int availableGlyphLength, int numberOfSignificantDigits, Preferences::PrintFloatMode mode);
|
||||||
|
|
||||||
class Long final {
|
class Long final {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ int FloatNode<T>::simplificationOrderSameType(const ExpressionNode * e, bool asc
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int FloatNode<T>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
int FloatNode<T>::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||||
return PrintFloat::ConvertFloatToText(m_value, buffer, bufferSize, numberOfSignificantDigits, floatDisplayMode);
|
return PrintFloat::ConvertFloatToText(m_value, buffer, bufferSize, PrintFloat::k_maxFloatGlyphLength, numberOfSignificantDigits, floatDisplayMode).CharLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Layout FloatNode<T>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
Layout FloatNode<T>::createLayout(Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const {
|
||||||
char buffer[PrintFloat::k_maxFloatBufferSize];
|
char buffer[PrintFloat::k_maxFloatCharSize];
|
||||||
int numberOfChars = serialize(buffer, PrintFloat::k_maxFloatBufferSize, floatDisplayMode, numberOfSignificantDigits);
|
int numberOfChars = serialize(buffer, PrintFloat::k_maxFloatCharSize, floatDisplayMode, numberOfSignificantDigits);
|
||||||
return LayoutHelper::String(buffer, numberOfChars);
|
return LayoutHelper::String(buffer, numberOfChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ int InfinityNode::serialize(char * buffer, int bufferSize, Preferences::PrintFlo
|
|||||||
if (bufferSize == 0) {
|
if (bufferSize == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return PrintFloat::ConvertFloatToText<float>(m_negative ? -INFINITY : INFINITY, buffer, bufferSize, numberOfSignificantDigits, floatDisplayMode);
|
return PrintFloat::ConvertFloatToText<float>(m_negative ? -INFINITY : INFINITY, buffer, bufferSize, PrintFloat::k_maxFloatGlyphLength, numberOfSignificantDigits, floatDisplayMode).CharLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> Evaluation<T> InfinityNode::templatedApproximate() const {
|
template<typename T> Evaluation<T> InfinityNode::templatedApproximate() const {
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ int Integer::serialize(char * buffer, int bufferSize) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (isOverflow()) {
|
if (isOverflow()) {
|
||||||
return PrintFloat::ConvertFloatToText<float>(m_negative ? -INFINITY : INFINITY, buffer, bufferSize, PrintFloat::k_numberOfStoredSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
return PrintFloat::ConvertFloatToText<float>(m_negative ? -INFINITY : INFINITY, buffer, bufferSize, PrintFloat::k_maxFloatGlyphLength, PrintFloat::k_numberOfStoredSignificantDigits, Preferences::PrintFloatMode::Decimal).CharLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer base(10);
|
Integer base(10);
|
||||||
@@ -185,7 +185,7 @@ int Integer::serialize(char * buffer, int bufferSize) const {
|
|||||||
d.quotient.isZero())) {
|
d.quotient.isZero())) {
|
||||||
char c = char_from_digit(d.remainder.isZero() ? 0 : d.remainder.digit(0));
|
char c = char_from_digit(d.remainder.isZero() ? 0 : d.remainder.digit(0));
|
||||||
if (length >= bufferSize-1) {
|
if (length >= bufferSize-1) {
|
||||||
return PrintFloat::ConvertFloatToText<float>(NAN, buffer, bufferSize, PrintFloat::k_numberOfStoredSignificantDigits, Preferences::PrintFloatMode::Decimal);
|
return PrintFloat::ConvertFloatToText<float>(NAN, buffer, bufferSize, PrintFloat::k_maxFloatGlyphLength, PrintFloat::k_numberOfStoredSignificantDigits, Preferences::PrintFloatMode::Decimal).CharLength;
|
||||||
}
|
}
|
||||||
length += SerializationHelper::CodePoint(buffer + length, bufferSize - length, c);
|
length += SerializationHelper::CodePoint(buffer + length, bufferSize - length, c);
|
||||||
d = udiv(d.quotient, base);
|
d = udiv(d.quotient, base);
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void PrintFloat::PrintLongWithDecimalMarker(char * buffer, int bufferLength, Lon
|
|||||||
* in first position. When called by ConvertFloatToText, the buffer length is
|
* in first position. When called by ConvertFloatToText, the buffer length is
|
||||||
* always > 0 as we asserted a minimal number of available chars. */
|
* always > 0 as we asserted a minimal number of available chars. */
|
||||||
assert(bufferLength > 0 && decimalMarkerPosition != 0);
|
assert(bufferLength > 0 && decimalMarkerPosition != 0);
|
||||||
constexpr int tempBufferSize = PrintFloat::k_maxFloatBufferSize;
|
constexpr int tempBufferSize = PrintFloat::k_maxFloatCharSize;
|
||||||
char tempBuffer[tempBufferSize];
|
char tempBuffer[tempBufferSize];
|
||||||
int intLength = i.serialize(tempBuffer, tempBufferSize);
|
int intLength = i.serialize(tempBuffer, tempBufferSize);
|
||||||
int firstDigitChar = UTF8Helper::CodePointIs(tempBuffer, '-') ? 1 : 0;
|
int firstDigitChar = UTF8Helper::CodePointIs(tempBuffer, '-') ? 1 : 0;
|
||||||
@@ -128,30 +128,30 @@ void PrintFloat::PrintLongWithDecimalMarker(char * buffer, int bufferLength, Lon
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
int PrintFloat::ConvertFloatToText(T f, char * buffer, int bufferSize,
|
PrintFloat::TextLengths PrintFloat::ConvertFloatToText(T f, char * buffer, int bufferSize, int glyphLength,
|
||||||
int numberOfSignificantDigits, Preferences::PrintFloatMode mode)
|
int numberOfSignificantDigits, Preferences::PrintFloatMode mode)
|
||||||
{
|
{
|
||||||
assert(numberOfSignificantDigits > 0);
|
assert(numberOfSignificantDigits > 0);
|
||||||
assert(bufferSize > 0);
|
assert(bufferSize > 0);
|
||||||
|
|
||||||
/* Truncate the buffer if needed.
|
/* Assert that the glyphLength is capped.
|
||||||
* Example: 1+1.234E-30+... in decimal mode, because we do not want the fill
|
* Example: 1+1.234E-30+... in decimal mode, because we do not want the fill
|
||||||
* the buffer with the decimal version of 1.234E-30. */
|
* the buffer with the decimal version of 1.234E-30. */
|
||||||
int truncatedBufferSize = minInt(PrintFloat::k_maxFloatBufferSize, bufferSize);
|
assert(glyphLength < k_maxFloatGlyphLength);
|
||||||
|
|
||||||
int numberOfZerosRemoved = 0;
|
TextLengths requiredLengths = ConvertFloatToTextPrivate(f, buffer, bufferSize, glyphLength, numberOfSignificantDigits, mode);
|
||||||
int requiredLength = ConvertFloatToTextPrivate(f, buffer, truncatedBufferSize, numberOfSignificantDigits, mode, &numberOfZerosRemoved);
|
|
||||||
/* If the required buffer size overflows the buffer size, we force the display
|
/* If the required buffer size overflows the buffer size, we force the display
|
||||||
* mode to scientific. */
|
* mode to scientific. */
|
||||||
if (mode == Preferences::PrintFloatMode::Decimal && requiredLength >= truncatedBufferSize) {
|
if (mode == Preferences::PrintFloatMode::Decimal && (requiredLengths.CharLength > bufferSize - 1 || requiredLengths.GlyphLength > glyphLength)) {
|
||||||
requiredLength = ConvertFloatToTextPrivate(f, buffer, truncatedBufferSize, numberOfSignificantDigits, Preferences::PrintFloatMode::Scientific, &numberOfZerosRemoved);
|
requiredLengths = ConvertFloatToTextPrivate(f, buffer, bufferSize, glyphLength, numberOfSignificantDigits, Preferences::PrintFloatMode::Scientific);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiredLength >= truncatedBufferSize) {
|
if (requiredLengths.CharLength > bufferSize - 1 || requiredLengths.GlyphLength > glyphLength) {
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
return 0;
|
/* We still return the required sizes even if we could not write the float
|
||||||
|
* in the buffer in order to indicate that we overflew the buffer. */
|
||||||
}
|
}
|
||||||
return requiredLength;
|
return requiredLengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PrintFloat::EngineeringExponentFromBase10Exponent(int exponent) {
|
int PrintFloat::EngineeringExponentFromBase10Exponent(int exponent) {
|
||||||
@@ -163,37 +163,43 @@ int PrintFloat::EngineeringExponentFromBase10Exponent(int exponent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, int numberOfSignificantDigits, Preferences::PrintFloatMode mode, int * numberOfRemovedZeros) {
|
PrintFloat::TextLengths PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, int glyphLength, int numberOfSignificantDigits, Preferences::PrintFloatMode mode) {
|
||||||
assert(numberOfSignificantDigits > 0);
|
assert(numberOfSignificantDigits > 0);
|
||||||
assert(bufferSize > 0);
|
assert(bufferSize > 0);
|
||||||
|
assert(glyphLength > 0 && glyphLength < k_maxFloatGlyphLength);
|
||||||
|
int availableCharLength = minInt(bufferSize-1, glyphLength);
|
||||||
|
TextLengths exceptionResult = {.CharLength = bufferSize, .GlyphLength = glyphLength+1};
|
||||||
//TODO: accelerate for f between 0 and 10 ?
|
//TODO: accelerate for f between 0 and 10 ?
|
||||||
if (std::isinf(f)) {
|
if (std::isinf(f)) {
|
||||||
// Infinity
|
// Infinity
|
||||||
bool writeMinusSign = f < 0;
|
bool writeMinusSign = f < 0;
|
||||||
assert(UTF8Decoder::CharSizeOfCodePoint('-') == 1);
|
assert(UTF8Decoder::CharSizeOfCodePoint('-') == 1);
|
||||||
int requiredLength = (writeMinusSign ? 1 : 0) + Infinity::NameSize() - 1;
|
int requiredCharLength = (writeMinusSign ? 1 : 0) + Infinity::NameSize() - 1;
|
||||||
if (requiredLength > bufferSize - 1) {
|
TextLengths requiredTextLengths = {.CharLength = requiredCharLength, .GlyphLength = requiredCharLength};
|
||||||
|
if (requiredCharLength > availableCharLength) {
|
||||||
// We will not be able to print
|
// We will not be able to print
|
||||||
return requiredLength;
|
return requiredTextLengths;
|
||||||
}
|
}
|
||||||
// Write inf or -inf
|
// Write inf or -inf
|
||||||
int currentChar = 0;
|
int currentChar = 0;
|
||||||
if (f < 0) {
|
if (f < 0) {
|
||||||
currentChar+= SerializationHelper::CodePoint(buffer, bufferSize, '-');
|
currentChar += SerializationHelper::CodePoint(buffer, bufferSize, '-');
|
||||||
}
|
}
|
||||||
assert(bufferSize - currentChar > 0);
|
assert(bufferSize - currentChar > 0);
|
||||||
strlcpy(buffer+currentChar, Infinity::Name(), bufferSize-currentChar);
|
strlcpy(buffer+currentChar, Infinity::Name(), bufferSize-currentChar);
|
||||||
return requiredLength;
|
return requiredTextLengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::isnan(f)) {
|
if (std::isnan(f)) {
|
||||||
// Nan
|
// Nan
|
||||||
constexpr int requiredLength = Undefined::NameSize() - 1;
|
constexpr int requiredCharLength = Undefined::NameSize() - 1;
|
||||||
if (requiredLength - 1 > bufferSize - 1) {
|
constexpr TextLengths requiredTextLengths = {.CharLength = requiredCharLength, .GlyphLength = requiredCharLength};
|
||||||
|
if (requiredCharLength > availableCharLength) {
|
||||||
// We will not be able to print
|
// We will not be able to print
|
||||||
return requiredLength;
|
return requiredTextLengths;
|
||||||
}
|
}
|
||||||
return strlcpy(buffer, Undefined::Name(), bufferSize);
|
strlcpy(buffer, Undefined::Name(), bufferSize);
|
||||||
|
return requiredTextLengths;
|
||||||
}
|
}
|
||||||
|
|
||||||
int exponentInBase10 = IEEE754<T>::exponentBase10(f);
|
int exponentInBase10 = IEEE754<T>::exponentBase10(f);
|
||||||
@@ -227,7 +233,7 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
* displaying 12345 with 2 significant digis in Decimal mode for instance.
|
* displaying 12345 with 2 significant digis in Decimal mode for instance.
|
||||||
* This exception is caught by ConvertFloatToText and forces the mode to
|
* This exception is caught by ConvertFloatToText and forces the mode to
|
||||||
* Scientific */
|
* Scientific */
|
||||||
return bufferSize + 1;
|
return exceptionResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct the number of digits in mantissa after rounding
|
// Correct the number of digits in mantissa after rounding
|
||||||
@@ -275,9 +281,6 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
assert(mantissa < 1000);
|
assert(mantissa < 1000);
|
||||||
Long::MultiplySmallLongByTen(dividend);
|
Long::MultiplySmallLongByTen(dividend);
|
||||||
}
|
}
|
||||||
if (numberOfRemovedZeros != nullptr) {
|
|
||||||
*numberOfRemovedZeros = -numberOfZeroesToAdd;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removeZeroes) {
|
if (removeZeroes) {
|
||||||
@@ -298,12 +301,9 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
Long::DivisionByTen(dividend, "ient, &digit);
|
Long::DivisionByTen(dividend, "ient, &digit);
|
||||||
numberOfZerosRemoved++;
|
numberOfZerosRemoved++;
|
||||||
}
|
}
|
||||||
if (numberOfCharsForMantissaWithoutSign > bufferSize - 1) {
|
if (numberOfCharsForMantissaWithoutSign > availableCharLength) {
|
||||||
// Escape now if the true number of needed digits is not required
|
// Escape now if the true number of needed digits is not required
|
||||||
return bufferSize + 1;
|
return exceptionResult;
|
||||||
}
|
|
||||||
if (numberOfRemovedZeros != nullptr) {
|
|
||||||
*numberOfRemovedZeros = numberOfZerosRemoved;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,9 +317,9 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
assert(UTF8Decoder::CharSizeOfCodePoint('.') == 1);
|
assert(UTF8Decoder::CharSizeOfCodePoint('.') == 1);
|
||||||
numberOfCharsForMantissaWithoutSign++;
|
numberOfCharsForMantissaWithoutSign++;
|
||||||
}
|
}
|
||||||
if (numberOfCharsForMantissaWithoutSign > bufferSize - 1) {
|
if (numberOfCharsForMantissaWithoutSign > availableCharLength) {
|
||||||
// Escape now if the true number of needed digits is not required
|
// Escape now if the true number of needed digits is not required
|
||||||
return bufferSize + 1;
|
return exceptionResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the position of the decimal marker position */
|
/* Find the position of the decimal marker position */
|
||||||
@@ -340,9 +340,9 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
/* Part III: Sign */
|
/* Part III: Sign */
|
||||||
|
|
||||||
int numberOfCharsForMantissaWithSign = numberOfCharsForMantissaWithoutSign + (f >= 0 ? 0 : 1);
|
int numberOfCharsForMantissaWithSign = numberOfCharsForMantissaWithoutSign + (f >= 0 ? 0 : 1);
|
||||||
if (numberOfCharsForMantissaWithSign > bufferSize - 1) {
|
if (numberOfCharsForMantissaWithSign > availableCharLength) {
|
||||||
// Exception 2: we will overflow the buffer
|
// Exception 2: we will overflow the buffer
|
||||||
return bufferSize + 1;
|
return exceptionResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Part IV: Exponent */
|
/* Part IV: Exponent */
|
||||||
@@ -360,15 +360,20 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
assert(UTF8Decoder::CharSizeOfCodePoint('-') == 1);
|
assert(UTF8Decoder::CharSizeOfCodePoint('-') == 1);
|
||||||
// Print mantissa
|
// Print mantissa
|
||||||
bool doNotWriteExponent = (mode == Preferences::PrintFloatMode::Decimal) || (exponent == 0);
|
bool doNotWriteExponent = (mode == Preferences::PrintFloatMode::Decimal) || (exponent == 0);
|
||||||
int neededNumberOfChars = numberOfCharsForMantissaWithSign + (doNotWriteExponent ? 0 : UTF8Decoder::CharSizeOfCodePoint(UCodePointLatinLetterSmallCapitalE) + numberOfCharExponent);
|
int neededNumberOfChars = numberOfCharsForMantissaWithSign;
|
||||||
if (neededNumberOfChars > bufferSize - 1) {
|
int neededNumberOfGlyphs = numberOfCharsForMantissaWithSign;
|
||||||
|
if (!doNotWriteExponent) {
|
||||||
|
neededNumberOfChars += UTF8Decoder::CharSizeOfCodePoint(UCodePointLatinLetterSmallCapitalE) + numberOfCharExponent;
|
||||||
|
neededNumberOfGlyphs += 1 + numberOfCharExponent;
|
||||||
|
}
|
||||||
|
if (neededNumberOfChars > bufferSize - 1 || neededNumberOfGlyphs > glyphLength) {
|
||||||
// Exception 3: We are about to overflow the buffer.
|
// Exception 3: We are about to overflow the buffer.
|
||||||
return neededNumberOfChars;
|
return exceptionResult;
|
||||||
}
|
}
|
||||||
PrintLongWithDecimalMarker(buffer, numberOfCharsForMantissaWithSign, dividend, decimalMarkerPosition);
|
PrintLongWithDecimalMarker(buffer, numberOfCharsForMantissaWithSign, dividend, decimalMarkerPosition);
|
||||||
if (doNotWriteExponent) {
|
if (doNotWriteExponent) {
|
||||||
buffer[numberOfCharsForMantissaWithSign] = 0;
|
buffer[numberOfCharsForMantissaWithSign] = 0;
|
||||||
return numberOfCharsForMantissaWithSign;
|
return {.CharLength = numberOfCharsForMantissaWithSign, .GlyphLength = numberOfCharsForMantissaWithSign};
|
||||||
}
|
}
|
||||||
// Print exponent
|
// Print exponent
|
||||||
assert(numberOfCharsForMantissaWithSign < bufferSize);
|
assert(numberOfCharsForMantissaWithSign < bufferSize);
|
||||||
@@ -378,10 +383,10 @@ int PrintFloat::ConvertFloatToTextPrivate(T f, char * buffer, int bufferSize, in
|
|||||||
PrintLongWithDecimalMarker(buffer + currentNumberOfChar, numberOfCharExponent, dividend, -1);
|
PrintLongWithDecimalMarker(buffer + currentNumberOfChar, numberOfCharExponent, dividend, -1);
|
||||||
buffer[currentNumberOfChar + numberOfCharExponent] = 0;
|
buffer[currentNumberOfChar + numberOfCharExponent] = 0;
|
||||||
assert(neededNumberOfChars == currentNumberOfChar + numberOfCharExponent);
|
assert(neededNumberOfChars == currentNumberOfChar + numberOfCharExponent);
|
||||||
return currentNumberOfChar + numberOfCharExponent;
|
return {.CharLength = currentNumberOfChar + numberOfCharExponent, .GlyphLength = numberOfCharsForMantissaWithSign + 1 + numberOfCharExponent};
|
||||||
}
|
}
|
||||||
|
|
||||||
template int PrintFloat::ConvertFloatToText<float>(float, char*, int, int, Preferences::Preferences::PrintFloatMode);
|
template PrintFloat::TextLengths PrintFloat::ConvertFloatToText<float>(float, char*, int, int, int, Preferences::Preferences::PrintFloatMode);
|
||||||
template int PrintFloat::ConvertFloatToText<double>(double, char*, int, int, Preferences::Preferences::PrintFloatMode);
|
template PrintFloat::TextLengths PrintFloat::ConvertFloatToText<double>(double, char*, int, int, int, Preferences::Preferences::PrintFloatMode);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ void assert_float_prints_to(T a, const char * result, Preferences::PrintFloatMod
|
|||||||
memset(taggedBuffer, tag, taggedAreaSize);
|
memset(taggedBuffer, tag, taggedAreaSize);
|
||||||
char * buffer = taggedBuffer + tagSize;
|
char * buffer = taggedBuffer + tagSize;
|
||||||
|
|
||||||
PrintFloat::ConvertFloatToText<T>(a, buffer, bufferSize, significantDigits, mode);
|
PrintFloat::ConvertFloatToText<T>(a, buffer, bufferSize, glyphLengthForFloatWithPrecision(significantDigits), significantDigits, mode);
|
||||||
|
|
||||||
for (int i = 0; i < tagSize; i++) {
|
for (int i = 0; i < tagSize; i++) {
|
||||||
quiz_assert_print_if_failure(taggedBuffer[i] == tag, result);
|
quiz_assert_print_if_failure(taggedBuffer[i] == tag, result);
|
||||||
|
|||||||
Reference in New Issue
Block a user