modf以小数形式返回1:

时间:2010-10-07 17:32:54

标签: c++ integer double fractions fmodf

我有这个静态方法,它接收一个double并“切割”它的小数尾部,在点之后留下两位数。几乎几乎。我注意到了 它接收2.3它变成2.29。 0.3,1.3,3.3,4.3和102.3不会发生这种情况。 代码基本上将数字乘以100使用modf将整数值除以100并返回它。 这里代码捕获了这个特定的数字并打印出来:

static double dRound(double number) {

    bool c = false;
    if (number == 2.3)
        c = true;


    int factor = pow(10, 2);
    number *= factor;


    if (c) {
        cout << " number *= factor : " << number << endl;
        //number = 230;// When this is not marked as comment the code works well.
    }


    double returnVal;
    if (c){
        cout << " fractional : " << modf(number, &returnVal) << endl;
        cout << " integer : " <<returnVal << endl;
    }


    modf(number, &returnVal);
    return returnVal / factor;
}

打印出来:

数字* =因子:230

分数:1

整数:229

有谁知道为什么会这样,我该如何解决这个问题? 谢谢你,周末愉快。

2 个答案:

答案 0 :(得分:6)

请记住,浮点数不能完全代表十进制数。 2.3 * 100实际上给出229.99999999999997。因此modf返回229和0.9999999999999716。

但是,cout的格式默认只显示浮点数到6位小数。所以0.9999999999999716显示为1。


您可以(大致)使用浮点值表示的上限错误,以避免2.3错误:

#include <cmath>
#include <limits>
static double dRound(double d) {
   double inf = copysign(std::numeric_limits<double>::infinity(), d);
   double theNumberAfter = nextafter(d, inf);
   double epsilon = theNumberAfter - d;

   int factor = 100;
   d *= factor;
   epsilon *= factor/2;
   d += epsilon;

   double returnVal;
   modf(number, &returnVal);
   return returnVal / factor;
}

结果:http://www.ideone.com/ywmua

答案 1 :(得分:0)

这是一种没有舍入的方法:

double double_cut(double d)
{
    long long x = d * 100;
    return x/100.0;
}

即使你想根据小数点后的第3位进行舍入,这里有一个解决方案:

double double_cut_round(double d)
{
    long long x = d * 1000;

    if (x > 0)
        x += 5;
    else
        x -= 5;

    return x / 1000.0;
}