如何返回另一个浮点数的最接近的可表示浮点数的倍数?

时间:2019-01-23 14:20:21

标签: c++ algorithm floating-point

我有浮点数给出的值和步号,例如:

double step = 0.4;
double value = 47.7121;

对于我给出的每个值和步骤对,我需要返回该步骤的最接近的可表示浮点数倍数。

所以这是一些预期结果:

step = 0.4;
value = 47.7121;
===> it must snap to 47.6
result = 47.60000000000000142108547152020037174224853515625

step = 0.1;
value = 47.9435;
===> it must snap to 47.9
result = 47.89999999999999857891452847979962825775146484375

我只能使用以下形式的有理数do this(不是浮点数):

#include <iostream>
#include <math.h>

inline double SnapValue(double value, int numerator, int denominator) {
    return round(value * denominator / numerator) * numerator / denominator;
}

int main() {
    std::cout.precision(100);

    std::cout << "result: " << SnapValue(47.7121, 2, 5) << std::endl; // step = 0.4, value 47.7121
    std::cout << "result: " << SnapValue(47.9435, 1, 10) << std::endl; // step = 0.1, value 47.9435

    return 0;
}

但是,正如我所说,我没有任何合理的数字开头,只是浮点数。 你会怎么做?

2 个答案:

答案 0 :(得分:1)

我会这样

您的拳头示例:

    double step = 0.4;
    (float) (((int) (47.7121d / step + step / 2)) * step);

    -> 47.6

您的第二个示例:

    double step = 0.1;
    (float) (((int) (47.9435d / step + step / 2)) * step);

    -> 47.9

这部分需要最接近的值:+ step / 2

答案 1 :(得分:0)

使用std::round的非常简单的解决方案:

#include <cmath>
double nearest_step(double value, double step)
{
    return std::round(value/step)*step;
}

请注意,没有(确切)值为0.1的浮点数。与double最接近的1./100.1000000000000000055511151231257827021181583404541015625,即,在大多数情况下,您得到的数字会比预期的稍大。 (此外,除法的结果通常也不准确,因此在少数情况下,可能会舍入到错误的方向。)