为何调用std::trunc()保留两位小数时返回0?
问题:std::trunc()返回-0和0的原因分析
我曾遇到「单元测试明明值相等却失败」的问题,编写了如下代码期望保留小数点后两位,但运行后truncate_函数返回-0和0,想知道为何std::trunc()会返回0?
代码实现
#include "simulation.hpp" #include <cstdio> typedef double real; double truncate_(double f) { return std::trunc(f * 100.0); } int main() { //Simulation sim; //sim.run(); LennardJones lj(Constants::EPSILON, Constants::SIGMA, Constants::KB); Vec3 diatance(4.0, 4.0, 4.0); real attractive = lj.getPotentialAttractive(diatance); real repulsive = lj.getPotentialRepulsive(diatance); std::cout << attractive << std::endl; std::cout << repulsive << std::endl; real attractive2 = truncate_(attractive); real repulsive2 = truncate_(repulsive); std::cout << attractive2 << std::endl; std::cout << repulsive2 << std::endl; getchar(); // Wait for a keypress }
输出结果
-4.84292e-06 6.82474e-08 -0 0
原因分析
std::trunc的行为逻辑std::trunc的作用是直接截断浮点数的小数部分,仅保留整数部分。结合你的输入值来看:
attractive的值为-4.84292e-06,乘以100后得到-4.84292e-04(即-0.000484292),这个数的整数部分是0,由于原数符号为负,截断后返回**-0**(这是IEEE 754浮点数标准允许的特殊值,数值上和0相等,但符号位为1)。repulsive的值为6.82474e-08,乘以100后得到6.82474e-06(即0.00000682474),整数部分为0,截断后直接返回0。
- 保留小数点后两位的逻辑错误
你想要实现保留小数点后两位的功能,但当前代码只完成了「乘以100后截断」的步骤,漏掉了关键的「除以100」操作。正确的实现应该是:
double truncate_(double f) { return std::trunc(f * 100.0) / 100.0; }
调整后,attractive会被处理为-0.00,repulsive会被处理为0.00,才符合保留两位小数的预期。
- 单元测试失败的可能原因
单元测试失败大概率是因为:
- 测试用例预期的是保留两位小数后的非零值,但当前代码返回的是0,不符合预期;
- 部分测试框架或自定义比较逻辑会区分
-0和0的符号位,导致判定为不相等。
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

