Avoid returning negative zeroes in v2s_f32_rounded
This ensures that values roundtrip correctly since -0.0 and 0.0 correspond to the same normalized value.
This commit is contained in:
parent
af12853644
commit
0afe6852b3
2 changed files with 32 additions and 2 deletions
|
@ -10,6 +10,14 @@ Since there is no stable release yet, the changes are organized per day in
|
||||||
reverse chronological order. The main purpose of this document in its current
|
reverse chronological order. The main purpose of this document in its current
|
||||||
state is to list breaking changes.
|
state is to list breaking changes.
|
||||||
|
|
||||||
|
## [2023-04-27]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- The `v2s_f32_rounded()` formatter now avoids returning negative zero values
|
||||||
|
for roundtripping reasons since -0.0 and 0.0 correspond to the same normalized
|
||||||
|
value.
|
||||||
|
|
||||||
## [2023-04-24]
|
## [2023-04-24]
|
||||||
|
|
||||||
### Breaking changes
|
### Breaking changes
|
||||||
|
|
|
@ -13,9 +13,19 @@ use crate::util;
|
||||||
// TODO: The v2s and s2v naming convention isn't ideal, but at least it's unambiguous. Is there a
|
// TODO: The v2s and s2v naming convention isn't ideal, but at least it's unambiguous. Is there a
|
||||||
// better way to name these functions? Should we just split this up into two modules?
|
// better way to name these functions? Should we just split this up into two modules?
|
||||||
|
|
||||||
/// Round an `f32` value to always have a specific number of decimal digits.
|
/// Round an `f32` value to always have a specific number of decimal digits. Avoids returning
|
||||||
|
/// negative zero values to make sure string->value->string roundtrips work correctly. Otherwise
|
||||||
|
/// `-0.001` rounded to two digits would result in `-0.00`.
|
||||||
pub fn v2s_f32_rounded(digits: usize) -> Arc<dyn Fn(f32) -> String + Send + Sync> {
|
pub fn v2s_f32_rounded(digits: usize) -> Arc<dyn Fn(f32) -> String + Send + Sync> {
|
||||||
Arc::new(move |value| format!("{value:.digits$}"))
|
let rounding_multiplier = 10u32.pow(digits as u32) as f32;
|
||||||
|
Arc::new(move |value| {
|
||||||
|
// See above
|
||||||
|
if (value * rounding_multiplier).round() / rounding_multiplier == 0.0 {
|
||||||
|
format!("{:.digits$}", 0.0)
|
||||||
|
} else {
|
||||||
|
format!("{value:.digits$}")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format a `[0, 1]` number as a percentage. Does not include the percent sign, you should specify
|
/// Format a `[0, 1]` number as a percentage. Does not include the percent sign, you should specify
|
||||||
|
@ -324,6 +334,18 @@ pub fn s2v_bool_bypass() -> Arc<dyn Fn(&str) -> Option<bool> + Send + Sync> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
/// The rounding function should never return strings containing negative zero values.
|
||||||
|
#[test]
|
||||||
|
fn v2s_f32_rounded_negative_zero() {
|
||||||
|
let v2s = v2s_f32_rounded(2);
|
||||||
|
|
||||||
|
assert_eq!("0.00", v2s(-0.001));
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
assert_eq!("-0.01", v2s(-0.009));
|
||||||
|
assert_eq!("0.01", v2s(0.009));
|
||||||
|
}
|
||||||
|
|
||||||
// More of these validators could use tests, but this one in particular is tricky and I noticed
|
// More of these validators could use tests, but this one in particular is tricky and I noticed
|
||||||
// an issue where it didn't roundtrip correctly
|
// an issue where it didn't roundtrip correctly
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Reference in a new issue