【问题标题】:C++ floor() decreasing value by 1C++ floor() 将值减 1
【发布时间】:2014-02-19 23:11:54
【问题描述】:

我编写了这个函数来递归地将double 舍入到 N 位:

double RoundDouble(double value, unsigned int digits)
{
    if (value == 0.0)
        return value;
    string num = dtos(value);
    size_t found = num.find(".");
    string dec = "";
    if (found != string::npos)
        dec = num.substr(found + 1);
    else
        return value;
    if (dec.length() <= digits)
    {
        LogToFile("C:\\test.txt", "RETURN: " + dtos(value) + "\n\n\n");
        return value;
    }
    else
    {
        double p10 = pow(10, (dec.length() - 1));
        LogToFile("C:\\test.txt", "VALUE: " + dtos(value) + "\n");
        double mul = value * p10;
        LogToFile("C:\\test.txt", "MUL: " + dtos(mul) + "\n");
        double sum = mul + 0.5;
        LogToFile("C:\\test.txt", "SUM: " + dtos(sum) + "\n");
        double floored = floor(sum);
        LogToFile("C:\\test.txt", "FLOORED: " + dtos(floored) + "\n");
        double div = floored / p10;
        LogToFile("C:\\test.txt", "DIV: " + dtos(div) + "\n-------\n");
        return RoundDouble(div, digits);
    }
}

但是从日志文件来看,在某些情况下 floor() 会发生一些非常奇怪的事情......

这是一个良好计算的输出示例:

VALUE: 2.0108
MUL: 2010.8
SUM: 2011.3
FLOORED: 2011
DIV: 2.011
-------
VALUE: 2.011
MUL: 201.1
SUM: 201.6
FLOORED: 201
DIV: 2.01
-------
RETURN: 2.01

这是一个错误计算的输出示例:

VALUE: 67.6946
MUL: 67694.6
SUM: 67695.1
FLOORED: 67695
DIV: 67.695
-------
VALUE: 67.695
MUL: 6769.5
SUM: 6770
FLOORED: 6769 <= PROBLEM HERE
DIV: 67.69
-------
RETURN: 67.69

floor(6770) 不应该返回 6770 吗?为什么返回 6769?

【问题讨论】:

  • 因为它实际上不是 6770,而是非常接近它的东西。 What Every Computer Scientist Should Know About Floating-Point Arithmetic
  • "floor(6770) 不应该返回 6770 吗?"对于 6770 的小值,情况并非如此。
  • 尝试在地板上添加一个 epsilon 值,听起来该值确实是 6769,小数使其接近 6770。
  • 这么多可能的重复...
  • 所以不是 6770 而是类似 6769.9999(...)9 的东西?但是通过将该双精度转换为字符串,它会显示 6770。如果我从中获取字符串值然后将其转换回双精度呢?这是一个愚蠢的解决方案还是可行?

标签: c++ floor


【解决方案1】:

首先感谢大家的建议。 顺便说一句,目前“双倍到字符串 -> 字符串到双倍 -> 地板”解决方案似乎是唯一给出完全预期结果的解决方案。 所以我只需要更换:

double floored = floor(sum);

double floored = floor(stod(dtos(sum)));

如果有人有更好的解决方案,请发布。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2021-03-06
    • 2013-12-26
    相关资源
    最近更新 更多