1
0
Fork 0

Fix step size based formatting

This commit is contained in:
Robbert van der Helm 2022-02-13 18:03:45 +01:00
parent 19d2dc0a67
commit 990072f529

View file

@ -227,11 +227,19 @@ macro_rules! impl_plainparam {
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String { fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
let value = self.preview_plain(normalized); let value = self.preview_plain(normalized);
match (&self.value_to_string, include_unit) { match (&self.value_to_string, &self.step_size, include_unit) {
(Some(f), true) => format!("{}{}", f(value), self.unit), (Some(f), _, true) => format!("{}{}", f(value), self.unit),
(Some(f), false) => format!("{}", f(value)), (Some(f), _, false) => format!("{}", f(value)),
(None, true) => format!("{}{}", value, self.unit), (None, Some(step_size), true) => {
(None, false) => format!("{}", value), let num_digits = decimals_from_step_size(*step_size);
format!("{:.num_digits$}{}", value, self.unit)
}
(None, Some(step_size), false) => {
let num_digits = decimals_from_step_size(*step_size);
format!("{:.num_digits$}", value)
}
(None, None, true) => format!("{}{}", value, self.unit),
(None, None, false) => format!("{}", value),
} }
} }
@ -350,20 +358,7 @@ impl<T: Display + Copy> Display for PlainParam<T> {
match (&self.value_to_string, &self.step_size) { match (&self.value_to_string, &self.step_size) {
(Some(func), _) => write!(f, "{}{}", func(self.value), self.unit), (Some(func), _) => write!(f, "{}{}", func(self.value), self.unit),
(None, Some(step_size)) => { (None, Some(step_size)) => {
// Determine the number of digits based on the step size. We'll perform some let num_digits = decimals_from_step_size(*step_size);
// rounding to ignore spurious extra precision caused by the floating point
// quantization.
const SCALE: f32 = 1_000_000.0; // 10.0f32.powi(f32::DIGITS as i32)
let step_size = (step_size * SCALE).round() / SCALE;
let mut num_digits = 0usize;
for decimals in 0..f32::DIGITS as usize {
if step_size * decimals as f32 >= 1.0 {
num_digits = decimals;
break;
}
}
write!(f, "{:.num_digits$}{}", self.value, self.unit) write!(f, "{:.num_digits$}{}", self.value, self.unit)
} }
_ => write!(f, "{}{}", self.value, self.unit), _ => write!(f, "{}{}", self.value, self.unit),
@ -496,3 +491,21 @@ impl BoolParam {
self self
} }
} }
/// Caldculate how many decimals to round to when displaying a floating point value with a specific
/// step size. We'll perform some rounding to ignore spurious extra precision caused by the floating
/// point quantization.
fn decimals_from_step_size(step_size: f32) -> usize {
const SCALE: f32 = 1_000_000.0; // 10.0f32.powi(f32::DIGITS as i32)
let step_size = (step_size * SCALE).round() / SCALE;
let mut num_digits = 0;
for decimals in 0..f32::DIGITS as i32 {
if step_size * 10.0f32.powi(decimals) as f32 >= 1.0 {
num_digits = decimals;
break;
}
}
num_digits as usize
}