为什么像1.82这样简单的双打呢是1.819999999645634565360? [英] Why do simple doubles like 1.82 end up being 1.819999999645634565360?

查看:97
本文介绍了为什么像1.82这样简单的双打呢是1.819999999645634565360?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

为什么Visual Studio 2008告诉我.9 - .8999999999999995 = 0.00000000000000055511151231257827?

c ++

嘿所以我正在做一个返回的功能给出数字数字类型的数字,但是我有双重困难。

Hey so i'm making a function to return the number of a digits in a number data type given, but i'm having some trouble with doubles.

我通过将它乘以100亿,然后将数字1乘以1直到双倍结束为0,计算出数位数。在价值的两倍,说.7904我从来没有退出的功能,因为它不断取消数字,最终不会是0,因为.7904的回报最终是7,903,999,988而不是79.400亿。

I figure out how many digits are in it by multiplying it by like 10 billion and then taking away digits 1 by 1 until the double ends up being 0. however when putting in a double of value say .7904 i never exit the function as it keeps taking away digits which never end up being 0 as the resut of .7904 ends up being 7,903,999,988 and not 7,904,000,000.

我如何解决这个问题?谢谢=)!哦,我的代码上的任何其他反馈都是欢迎!

How can i solve this problem?? Thanks =) ! oh and any other feed back on my code is WELCOME!

这里是我的函数代码:

///////////////////////     Numb_Digits()   ////////////////////////////////////////////////////
        enum{DECIMALS = 10, WHOLE_NUMBS = 20, ALL = 30};
    template<typename T>
unsigned long int Numb_Digits(T numb, int scope)
{
        unsigned long int length= 0; 
    switch(scope){
        case DECIMALS:      numb-= (int)numb;   numb*=10000000000; // 10 bil (10 zeros)
            for(; numb != 0; length++)
                numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;

        case WHOLE_NUMBS:   numb= (int)numb;    numb*=10000000000; 
            for(; numb != 0; length++)
                numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;

        case ALL:           numb = numb;        numb*=10000000000;
            for(; numb != 0; length++)
                numb-=((int)(numb/pow((double)10, (double)(9-length))))* pow((double)10, (double)(9-length)); break;

        default: break;}
                                            return length;
};

int main()
{
    double test = 345.6457;
    cout << Numb_Digits(test, ALL) << endl; 
    cout << Numb_Digits(test, DECIMALS) << endl;
    cout << Numb_Digits(test, WHOLE_NUMBS) << endl;

    return 0;
}


推荐答案

这是因为C ++大多数其他语言)无法以无限精度存储浮点数。

This is because C++ (like most other languages) can not store floating point numbers with infinte precision.

浮点数存储如下:

*系数* 10 ^指数如果您使用基数10.

问题是,系数 exponent 存储为有限整数。

Floating points are stored like this:
sign * coefficient * 10^exponent if you're using base 10.
The problem is that both the coefficient and exponent are stored as finite integers.

这是在计算机程序中存储浮点的常见问题,您通常会一个微小的四舍五入错误。

This is a common problem with storing floating point in computer programs, you usually get a tiny rounding error.

最常见的处理方式是:


    <将数字存储为小数(x / y)
  • 使用允许小偏差的增量(如果abs(xy)< delta)

  • 使用可以完美精确存储浮点的GMP等第三方库。

关于计数小数的问题。 br>
没有任何交易方式如果您获得双倍的输入数据。您不能确定用户实际发送了1.819999999645634565360而不是1.82。

Regarding your question about counting decimals.
There is no way of dealing with this if you get a double as input. You cannot be sure that the user actually sent 1.819999999645634565360 and not 1.82.

您必须更改输入或更改您的功能的工作方式。

Either you have to change your input or change the way your function works.

可以在这里找到有关浮点的更多信息: http:// en。 wikipedia.org/wiki/Floating_point

More info on floating point can be found here: http://en.wikipedia.org/wiki/Floating_point

这篇关于为什么像1.82这样简单的双打呢是1.819999999645634565360?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆