Files
Upsilon/apps/shared/range_1D.cpp
Émilie Feral 98f2b8a11f [poincare][apps/shared] Use IEEE754::exponentInBase10 instead of
std::floor(std::log10()) to avoid precision issues when computing
the number of digits of a number
2019-10-03 10:31:25 +02:00

50 lines
1.4 KiB
C++

#include "range_1D.h"
#include <assert.h>
#include <ion.h>
#include <poincare/ieee754.h>
namespace Shared {
static inline float minFloat(float x, float y) { return x < y ? x : y; }
static inline float maxFloat(float x, float y) { return x > y ? x : y; }
void Range1D::setMin(float min, float lowerMaxFloat, float upperMaxFloat) {
min = clipped(min, false, lowerMaxFloat, upperMaxFloat);
if (std::isnan(min)) {
return;
}
m_min = min;
if (m_min >= m_max) {
m_max = min + defaultRangeLengthFor(min);
}
if (m_max - min < k_minFloat) {
m_max = clipped(min + k_minFloat, true, lowerMaxFloat, upperMaxFloat);
}
}
void Range1D::setMax(float max, float lowerMaxFloat, float upperMaxFloat) {
max = clipped(max, true, lowerMaxFloat, upperMaxFloat);
if (std::isnan(max)) {
return;
}
m_max = max;
if (m_min >= m_max) {
m_min = max - defaultRangeLengthFor(max);
}
if (max-m_min < k_minFloat) {
m_min = clipped(max - k_minFloat, false, lowerMaxFloat, upperMaxFloat);
}
}
float Range1D::defaultRangeLengthFor(float position) {
return std::pow(10.0f, Poincare::IEEE754<float>::exponentBase10(position)-1.0f);
}
float Range1D::clipped(float x, bool isMax, float lowerMaxFloat, float upperMaxFloat) {
float maxF = isMax ? upperMaxFloat : lowerMaxFloat;
float minF = isMax ? -lowerMaxFloat : -upperMaxFloat;
return maxFloat(minF, minFloat(x, maxF));
}
}