From 0c1603e15e4152f62f4b9d97665b5591ee271167 Mon Sep 17 00:00:00 2001 From: Michael Votaw Date: Mon, 3 Mar 2025 19:24:57 -0600 Subject: [PATCH] Round bpm and beat to 3 decimal places using std::round() instead of just truncating to 3 decimal places (fixes discrepancy in GS hash generation) --- src/RageUtil.cpp | 10 ++++++++++ src/RageUtil.h | 3 ++- src/Steps.cpp | 9 +++------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index dc37a2d137..d3f5c313f3 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -370,6 +371,15 @@ RString FormatNumberAndSuffix( int i ) return NUM_PREFIX.GetValue() + ssprintf("%i", i) + sSuffix; } +RString NormalizeDecimal(float num) +{ + float mult = 1000.0f; + float rounded = std::round(num * mult) / mult; + std::ostringstream os; + os << std::fixed << std::setprecision(3) << rounded; + return os.str(); +} + struct tm GetLocalTime() { const time_t t = time(nullptr); diff --git a/src/RageUtil.h b/src/RageUtil.h index b50f4fbea1..d9b9321d46 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -349,7 +349,8 @@ inline RString PrettyPercent( int fNumerator, int fDenominator ) { return Pretty RString Commify( int iNum ); RString Commify(const RString& num, const RString& sep= ",", const RString& dot= "."); RString FormatNumberAndSuffix( int i ); - +/* Round num to 3 decimal places and return as string with 3 decimal places */ +RString NormalizeDecimal(float num); struct tm GetLocalTime(); diff --git a/src/Steps.cpp b/src/Steps.cpp index 2d9806d9cb..10c90cd912 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include "StepParityGenerator.h" @@ -805,16 +804,14 @@ void Steps::CalculateGrooveStatsHash(bool forceRecalculate) TimingData * timingData = this->GetTimingData(); std::vector segments = timingData->GetTimingSegments(SEGMENT_BPM); std::vector bpmStrings; + bpmStrings.reserve(segments.size()); for (TimingSegment *segment : segments) { BPMSegment *bpmSegment = ToBPM(segment); float beat = bpmSegment->GetBeat(); float bpm = bpmSegment->GetBPM(); - std::ostringstream os; - os << std::fixed << std::setprecision(3) << beat; - os << "="; - os << std::fixed << std::setprecision(3) << bpm; - bpmStrings.push_back(os.str()); + RString segmentStr = ssprintf("%s=%s", NormalizeDecimal(beat).c_str(), NormalizeDecimal(bpm).c_str()); + bpmStrings.push_back(segmentStr); } RString bpmString = join(",", bpmStrings);