You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何用float进行C++ chrono时长减法运算会得到错误结果?

问题分析:float精度导致的chrono时间计算错误

问题场景

我们需要从一个纳秒级时间戳中减去2.5秒,编写了如下C++代码:

nanoseconds current_ts{1645546551805673592};                            
float diff = 2.5;
nanoseconds target_ts = duration_cast<nanoseconds>(current_ts - (seconds{1} * diff));

运行后得到的结果并非预期的1645546549305673592,而是错误的1645546556876652544。测试发现:将diff改为double类型,或者把current_ts移到duration_cast外部(如下方代码中的target_ts),运算结果就会正常。

最小复现代码:

#include <chrono>
#include <iostream>
#include <list>

int main() {
  using namespace std::chrono;

  nanoseconds current_ts{1645546551805673592};
  float context_pre_event_image_sec_ = 2.5;
  nanoseconds target_ts = current_ts - duration_cast<nanoseconds>((seconds{1} * context_pre_event_image_sec_));
  nanoseconds target_ts_2 = duration_cast<nanoseconds>(current_ts - (seconds{1} * context_pre_event_image_sec_));

  std::cout << current_ts.count() << std::endl;
  std::cout << target_ts.count() << std::endl;
  std::cout << target_ts_2.count() << std::endl;
}

其中第二个输出为预期结果,第三个为错误结果。

问题原因

核心原因是float的精度不足以容纳大数值的纳秒时间戳,具体细节如下:

1. 错误表达式的运算逻辑(target_ts_2)

对于duration_cast<nanoseconds>(current_ts - (seconds{1} * diff)):

  • seconds{1} * diff会生成一个float类型的秒级duration(std::chrono::duration<float>)。
  • 当current_ts(纳秒级整数duration)与这个浮点duration做减法时,current_ts会被隐式转换为float类型的纳秒级duration——也就是把1645546551805673592这个19位的大整数转成float。
  • float的有效二进制位数仅为24位(对应约7-8位十进制有效数字),完全无法精确存储这个大整数,转换后会丢失大量低位信息,变成一个近似值。
  • 后续的减法运算基于这个近似值进行,最终转换回纳秒整数时,结果自然与预期不符。

2. 正确表达式的运算逻辑(target_ts)

对于current_ts - duration_cast<nanoseconds>((seconds{1} * diff)):

  • 先将seconds{1} * diff(2.5秒)通过duration_cast转换为纳秒级整数duration:2500000000,这个数值在float的精度范围内(可精确表示)。
  • 后续用current_ts这个精确的整数直接减去该精确值,全程是整数运算,没有任何精度损失,因此结果正确。

3. 改用double类型后正常的原因

double类型的有效二进制位数为53位(对应约15-17位十进制有效数字),虽然1645546551805673592是19位数字,转成double仍会丢失部分低位,但2.5秒对应的2500000000远小于double的精度覆盖范围,因此current_ts - 2.5秒的结果在double中仍能保持足够的精度,转换回纳秒整数时可以得到正确结果。

内容的提问来源于stack exchange,提问作者Andrei Liaukovich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:04:52