mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Fix floating point handling in filter intervals
Due to floating-point rounding and representation errors, filters could wrongly display results incongruous with the wedge display text (ie. a beatmap with the BPM of 139.99999 would be displayed as having 140 BPM and also pass the bpm<140 filter). Apply tolerance when parsing floating-point constraints. The tolerance chosen is half of what the UI displays for the particular values (so for example half of 0.1 for AR/DR/CS, 0.01 for stars, etc.) Tests updated accordingly.
This commit is contained in:
@ -25,23 +25,23 @@ namespace osu.Game.Screens.Select
|
||||
switch (key)
|
||||
{
|
||||
case "stars" when parseFloatWithPoint(value, out var stars):
|
||||
updateCriteriaRange(ref criteria.StarDifficulty, op, stars);
|
||||
updateCriteriaRange(ref criteria.StarDifficulty, op, stars, 0.01f / 2);
|
||||
break;
|
||||
|
||||
case "ar" when parseFloatWithPoint(value, out var ar):
|
||||
updateCriteriaRange(ref criteria.ApproachRate, op, ar);
|
||||
updateCriteriaRange(ref criteria.ApproachRate, op, ar, 0.1f / 2);
|
||||
break;
|
||||
|
||||
case "dr" when parseFloatWithPoint(value, out var dr):
|
||||
updateCriteriaRange(ref criteria.DrainRate, op, dr);
|
||||
updateCriteriaRange(ref criteria.DrainRate, op, dr, 0.1f / 2);
|
||||
break;
|
||||
|
||||
case "cs" when parseFloatWithPoint(value, out var cs):
|
||||
updateCriteriaRange(ref criteria.CircleSize, op, cs);
|
||||
updateCriteriaRange(ref criteria.CircleSize, op, cs, 0.1f / 2);
|
||||
break;
|
||||
|
||||
case "bpm" when parseDoubleWithPoint(value, out var bpm):
|
||||
updateCriteriaRange(ref criteria.BPM, op, bpm);
|
||||
updateCriteriaRange(ref criteria.BPM, op, bpm, 0.01d / 2);
|
||||
break;
|
||||
|
||||
case "length" when parseDoubleWithPoint(value.TrimEnd('m', 's', 'h'), out var length):
|
||||
@ -99,29 +99,67 @@ namespace osu.Game.Screens.Select
|
||||
|
||||
private static void updateCriteriaRange(ref FilterCriteria.OptionalRange<float> range, string op, float value, float tolerance = 0.05f)
|
||||
{
|
||||
updateCriteriaRange(ref range, op, value);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
default:
|
||||
return;
|
||||
|
||||
case "=":
|
||||
case ":":
|
||||
range.Min = value - tolerance;
|
||||
range.Max = value + tolerance;
|
||||
break;
|
||||
|
||||
case ">":
|
||||
range.Min = value + tolerance;
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
case ">:":
|
||||
range.Min = value - tolerance;
|
||||
break;
|
||||
|
||||
case "<":
|
||||
range.Max = value - tolerance;
|
||||
break;
|
||||
|
||||
case "<=":
|
||||
case "<:":
|
||||
range.Max = value + tolerance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateCriteriaRange(ref FilterCriteria.OptionalRange<double> range, string op, double value, double tolerance = 0.05)
|
||||
{
|
||||
updateCriteriaRange(ref range, op, value);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
default:
|
||||
return;
|
||||
|
||||
case "=":
|
||||
case ":":
|
||||
range.Min = value - tolerance;
|
||||
range.Max = value + tolerance;
|
||||
break;
|
||||
|
||||
case ">":
|
||||
range.Min = value + tolerance;
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
case ">:":
|
||||
range.Min = value - tolerance;
|
||||
break;
|
||||
|
||||
case "<":
|
||||
range.Max = value - tolerance;
|
||||
break;
|
||||
|
||||
case "<=":
|
||||
case "<:":
|
||||
range.Max = value + tolerance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user