温度校验代码中if条件含cur_temp - 0.的原因及假设验证
关于传感器温度校验代码的疑问解答
先明确代码核心逻辑
这段代码的温度校验规则很明确:
- 当没有历史温度记录时,如果当前温度的绝对值接近0(误差小于1e-6),判定为温度错误;
- 当有历史温度记录时,如果当前温度和历史温度的差值绝对值超过100.0,判定为温度错误。
你的疑问逐一解答
1. 为什么要写cur_temp - 0.(触发float转double)?
0.是double类型的字面量,float类型的cur_temp和它做减法时,会触发C++的隐式类型转换:cur_temp被自动提升为double类型后再计算差值。这么做的原因大概率是这两点:
- 编码习惯:开发者可能习惯用double类型做浮点运算,避免float精度不足的潜在问题(而且float转double不会损失精度,double的精度完全覆盖float);
- 类型统一:后面的比较值
1e-6和100.0都是double类型,转成double后计算和比较时,不会出现跨类型运算的隐式转换警告或潜在问题。
其实这段代码等价于std::abs(static_cast<double>(cur_temp)) < 1e-6,甚至直接写std::abs(cur_temp) < 1e-6(此时1e-6会被转为float)也能达到同样效果,只是开发者选择了通过-0.这种方式来显式触发类型转换。
2. 关于「需接受负读数但要排除接近0的float值」的假设是否正确?
这个假设部分正确:
- 代码确实允许负读数:比如第一次输入
-5.0,因为std::abs(-5.0 - 0.) = 5.0 > 1e-6,不会触发第一个错误分支;后续输入-10.0,和历史值差为5.0,也不会触发第二个错误分支。 - 但不是「排除接近0的float值」,而是仅在第一次无历史记录时,接近0的温度(无论正负)会被判定为错误。如果是后续读数,即使当前温度接近0,只要和历史温度的差值绝对值不超过100.0,就不会触发错误。
核心条件代码拆解
把核心条件的含义直白翻译一下:
// 分支1:没有历史温度,且当前温度接近0(正、负接近0都算) (!prev_temp && std::abs(cur_temp - 0.) < 1e-6) // 分支2:有历史温度,且当前温度和历史温度的差超过100度(不管是骤升还是骤降) || (prev_temp && std::abs(prev_temp.value() - cur_temp) > 100.0)
内容的提问来源于stack exchange,提问作者Douglas B
相关产品推荐
相关产品推荐

