mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
Merge pull request #109887 from aaronfranke/range-rescale
Rescale values to better utilize R128 range before snapping
This commit is contained in:
commit
b267c2fc6c
1 changed files with 32 additions and 15 deletions
|
@ -33,7 +33,21 @@
|
|||
#include "thirdparty/misc/r128.h"
|
||||
|
||||
double Range::_snapped_r128(double p_value, double p_step) {
|
||||
if (p_step != 0) {
|
||||
if (p_step == 0.0) {
|
||||
return p_value;
|
||||
}
|
||||
if (p_value > (1e18 * p_step) || p_value < -(1e18 * p_step)) {
|
||||
// If the value goes outside of the range R128 supports, fallback to normal snapping.
|
||||
return Math::snapped(p_value, p_step);
|
||||
}
|
||||
// Rescale values to better utilize R128's range before snapping.
|
||||
// R128 is fixed-precision with 64 bits after the decimal point, but double already uses 53 of those,
|
||||
// so a step size finer than 2^-11 will lose precision, and in practice even 1e-3 can be problematic.
|
||||
// By rescaling the value and step, we can shift precision into the higher bits (effectively turning R128 into a makeshift float).
|
||||
const int decimals = 14 - Math::floor(std::log10(MAX(Math::abs(p_value), p_step)));
|
||||
const double scale = Math::pow(10.0, decimals);
|
||||
p_value *= scale;
|
||||
p_step *= scale;
|
||||
// All these lines are the equivalent of: p_value = Math::floor(p_value / p_step + 0.5) * p_step;
|
||||
// Convert to String to force rounding to a decimal value (not a binary one).
|
||||
String step_str = String::num(p_step);
|
||||
|
@ -47,8 +61,11 @@ double Range::_snapped_r128(double p_value, double p_step) {
|
|||
r128Add(&value_r128, &value_r128, &half_r128);
|
||||
r128Floor(&value_r128, &value_r128);
|
||||
r128Mul(&value_r128, &value_r128, &step_r128);
|
||||
p_value = value_r128;
|
||||
if (scale != 1.0) {
|
||||
const R128 scale_r128 = R128(scale);
|
||||
r128Div(&value_r128, &value_r128, &scale_r128);
|
||||
}
|
||||
p_value = (double)value_r128;
|
||||
return p_value;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue