modf 返回 1 作为小数:

发布于 2024-09-26 16:57:42 字数 943 浏览 6 评论 0原文

我有这个静态方法,它接收一个 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;
}

它打印出:

number *= factor : 230

小数 : 1

整数 : 229

有谁知道为什么会发生这种情况以及我该如何解决这个问题? 谢谢,祝周末愉快。

I have this static method, it receives a double and "cuts" its fractional tail leaving two digits after the dot. works almost all the time. I have noticed that when
it receives 2.3 it turns it to 2.29. This does not happen for 0.3, 1.3, 3.3, 4.3 and 102.3.
Code basically multiplies the number by 100 uses modf divides the integer value by 100 and returns it.
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

fractional : 1

integer : 229

Does anybody know why this is happening and how can i fix this?
Thank you, and have a great weekend.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖凝香 2024-10-03 16:57:42

请记住,浮点数不能精确地表示十进制数。 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

Remember floating point number cannot represent decimal numbers exactly. 2.3 * 100 actually gives 229.99999999999997. Thus modf returns 229 and 0.9999999999999716.

However, cout's format will only display floating point numbers to 6 decimal places by default. So the 0.9999999999999716 is shown as 1.


You could use (roughly) the upper error limit that a value represents in floating point to avoid the 2.3 error:

#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

是你 2024-10-03 16:57:42

这是一种不四舍五入的方法:

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

即使您想根据小数点后第三位四舍五入,这里有一个解决方案:

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

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

    return x / 1000.0;
}

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:

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

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

    return x / 1000.0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文