如何在指定时长内实现数值递减至目标值?
C++实现指定时长内数值线性递减的方案
问题分析
你原代码的核心问题在于:试图一次性获取递减过程的结果并赋值给int变量,但数值递减是随时间变化的过程,无法通过单次调用直接得到最终值(除非阻塞程序直到完成,但这几乎没有实用价值)。
实用解决方案:非阻塞式实时获取当前值
这种方案适合游戏、UI动画等需要实时更新数值的场景,每次调用都能获取当前时间对应的递减数值。
方式1:使用类封装状态
#include <chrono> #include <cmath> #include <thread> #include <cstdio> class Decrementer { private: int start_val; int end_val; std::chrono::seconds total_duration; std::chrono::steady_clock::time_point start_time; public: Decrementer(int start, int end, int total_seconds) : start_val(start), end_val(end), total_duration(total_seconds), start_time(std::chrono::steady_clock::now()) {} int get_current() { const auto now = std::chrono::steady_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time); // 计算进度,确保不超过100% const double progress = std::min( static_cast<double>(elapsed.count()) / (total_duration.count() * 1000.0), 1.0 ); // 线性插值计算当前值 int current = start_val + static_cast<int>((end_val - start_val) * progress); // 防止因浮点计算误差导致数值超出目标范围 if (end_val < start_val) { return std::max(current, end_val); } else { return std::min(current, end_val); } } }; // 使用示例 int main() { Decrementer dec(2000, 0, 40); // 模拟每秒获取一次当前值 for (int i = 0; i < 45; ++i) { const int cool_variable = dec.get_current(); printf("第%d秒:当前值 = %d\n", i, cool_variable); std::this_thread::sleep_for(std::chrono::seconds(1)); } return 0; }
方式2:使用带状态的lambda
如果偏好函数式风格,可以通过工厂函数返回一个捕获状态的lambda,每次调用lambda获取当前值:
#include <chrono> #include <cmath> #include <functional> #include <thread> #include <cstdio> std::function<int()> make_decrementer(int start_val, int end_val, int total_seconds) { const auto start_time = std::chrono::steady_clock::now(); const std::chrono::seconds total_duration(total_seconds); return [=]() { const auto now = std::chrono::steady_clock::now(); const auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time); const double progress = std::min( static_cast<double>(elapsed.count()) / (total_duration.count() * 1000.0), 1.0 ); int current = start_val + static_cast<int>((end_val - start_val) * progress); if (end_val < start_val) { return std::max(current, end_val); } else { return std::min(current, end_val); } }; } // 使用示例 int main() { auto decrement = make_decrementer(2000, 0, 40); for (int i = 0; i < 45; ++i) { const int cool_variable = decrement(); printf("第%d秒:当前值 = %d\n", i, cool_variable); std::this_thread::sleep_for(std::chrono::seconds(1)); } return 0; }
阻塞式方案(仅作参考,实用性低)
如果必须阻塞程序直到数值递减完成,可以用以下代码,但会导致程序暂停指定时长:
#include <chrono> #include <thread> int decrement_blocking(int start_val, int end_val, int total_seconds) { std::this_thread::sleep_for(std::chrono::seconds(total_seconds)); return end_val; } // 使用示例(会阻塞40秒) int main() { int cool_variable = decrement_blocking(2000, 0, 40); return cool_variable; }
内容的提问来源于stack exchange,提问作者fadid
相关产品推荐
相关产品推荐

