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

为何调用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

原因分析

  1. 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。
  1. 保留小数点后两位的逻辑错误
    你想要实现保留小数点后两位的功能,但当前代码只完成了「乘以100后截断」的步骤,漏掉了关键的「除以100」操作。正确的实现应该是:
double truncate_(double f)
{
    return std::trunc(f * 100.0) / 100.0;
}

调整后,attractive会被处理为-0.00,repulsive会被处理为0.00,才符合保留两位小数的预期。

  1. 单元测试失败的可能原因
    单元测试失败大概率是因为:
  • 测试用例预期的是保留两位小数后的非零值,但当前代码返回的是0,不符合预期;
  • 部分测试框架或自定义比较逻辑会区分-0和0的符号位,导致判定为不相等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 13:00:30