简体   繁体   English

modf返回1作为小数:

[英]modf returns 1 as the fractional:

I have this static method, it receives a double and "cuts" its fractional tail leaving two digits after the dot. 我有这个静态方法,它收到一个double并“削减”其小数尾巴,在点后留下两位数字。 works almost all the time. 几乎一直都能工作。 I have noticed that when it receives 2.3 it turns it to 2.29. 我注意到,当它收到2.3时,它将变为2.29。 This does not happen for 0.3, 1.3, 3.3, 4.3 and 102.3. 对于0.3、1.3、3.3、4.3和102.3不会发生这种情况。 Code basically multiplies the number by 100 uses modf divides the integer value by 100 and returns it. 代码基本上将数字乘以100,使用modf将整数值除以100并返回。 Here the code catches this one specific number and prints out: 这里的代码捕获了这个特定的数字并打印出来:

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;
}

it prints out: 它输出:

number *= factor : 230 数字* =系数:230

fractional : 1 小数:1

integer : 229 整数:229

Does anybody know why this is happening and how can i fix this? 有人知道为什么会这样吗,我该如何解决? Thank you, and have a great weekend. 谢谢,祝您周末愉快。

Remember floating point number cannot represent decimal numbers exactly. 请记住,浮点数不能完全代表十进制数。 2.3 * 100 actually gives 229.99999999999997. 2.3 * 100实际上给出了229.99999999999997。 Thus modf returns 229 and 0.9999999999999716. 因此modf返回229和0.9999999999999716。

However, cout 's format will only display floating point numbers to 6 decimal places by default. 但是, cout的格式默认情况下仅将浮点数显示为6个小数位。 So the 0.9999999999999716 is shown as 1. 因此0.9999999999999716显示为1。


You could use (roughly) the upper error limit that a value represents in floating point to avoid the 2.3 error: 您可以(大约)使用值在浮点数中表示的错误上限,以避免出现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;
}

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

Here is a way without rounding: 这是一种不四舍五入的方法:

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

Even if you want rounding according to 3rd digit after decimal point, here is a solution: 即使您要根据小数点后的第3位舍入,这也是一种解决方案:

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

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

    return x / 1000.0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM