|
30 | 30 |
|
31 | 31 | #include "range.h" |
32 | 32 |
|
| 33 | +#include "thirdparty/misc/r128.h" |
| 34 | + |
| 35 | +double Range::_snapped_r128(double p_value, double p_step) { |
| 36 | + if (p_step != 0) { |
| 37 | + // All these lines are the equivalent of: p_value = Math::floor(p_value / p_step + 0.5) * p_step; |
| 38 | + // Convert to String to force rounding to a decimal value (not a binary one). |
| 39 | + String step_str = String::num(p_step); |
| 40 | + String value_str = String::num(p_value); |
| 41 | + R128 step_r128; |
| 42 | + R128 value_r128; |
| 43 | + const R128 half_r128 = R128(0.5); |
| 44 | + r128FromString(&step_r128, step_str.ascii().get_data(), nullptr); |
| 45 | + r128FromString(&value_r128, value_str.ascii().get_data(), nullptr); |
| 46 | + r128Div(&value_r128, &value_r128, &step_r128); |
| 47 | + r128Add(&value_r128, &value_r128, &half_r128); |
| 48 | + r128Floor(&value_r128, &value_r128); |
| 49 | + r128Mul(&value_r128, &value_r128, &step_r128); |
| 50 | + p_value = value_r128; |
| 51 | + } |
| 52 | + return p_value; |
| 53 | +} |
| 54 | + |
33 | 55 | PackedStringArray Range::get_configuration_warnings() const { |
34 | 56 | PackedStringArray warnings = Control::get_configuration_warnings(); |
35 | 57 |
|
@@ -140,9 +162,8 @@ void Range::_set_value_no_signal(double p_val) { |
140 | 162 |
|
141 | 163 | double Range::_calc_value(double p_val, double p_step) const { |
142 | 164 | if (p_step > 0) { |
143 | | - // TODO: In the future, change `step` to a more suitable type for more robust precise calculations. |
144 | 165 | // Subtract min to support cases like min = 0.1, step = 0.2, snaps to 0.1, 0.3, 0.5, etc. |
145 | | - p_val = Math::snapped(p_val - shared->min, p_step) + shared->min; |
| 166 | + p_val = _snapped_r128(p_val - shared->min, p_step) + shared->min; |
146 | 167 | } |
147 | 168 |
|
148 | 169 | if (_rounded_values) { |
|
0 commit comments