| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 908 人关注过本帖
标题:关于将小数转成二进制的问题,输入0.1结果不对,求高手指教!
只看楼主 加入收藏
歌舞伎町
Rank: 2
等 级:论坛游民
帖 子:30
专家分:38
注 册:2013-8-7
结帖率:66.67%
收藏
已结贴  问题点数:10 回复次数:10 
关于将小数转成二进制的问题,输入0.1结果不对,求高手指教!
本人写了一个将介于0和1之间的小数转成64位尾数的二进制数字序列,
经测试输入0.5,输出10000……
经测试输入0.75,输出110000……
以上数字结果正确

但是输入0.1的时候,结果如图
图片附件: 游客没有浏览图片的权限,请 登录注册

可以看到当计算完第27位的时候,程序就像停止计算了一样,后面全部输出0了,但是实际上0.1转成二进制数字序列应该是110011001100……无限循环的

请问高手们,为什么会出现这种情况?是我程序有问题还是其他的问题?
代码如下:
#include<stdio.h>
int main()
{
    float a;
    int i;
    scanf("%f",&a);
    for(i=1;i<65;i++)
    {
        a=a*2;
        if(a>=1)
        {
            a=a-1;
            printf("1");
        }
        else
        {
            printf("0");
        }
        if(i%8==0)
        {
            printf(" ");
        }
    }
    printf("\n");
    return(0);
}
搜索更多相关主题的帖子: include 二进制 
2013-08-10 01:32
歌舞伎町
Rank: 2
等 级:论坛游民
帖 子:30
专家分:38
注 册:2013-8-7
收藏
得分:0 
补充一点,测试环境Visual C++6.0

又测试0.01,结果如下:
图片附件: 游客没有浏览图片的权限,请 登录注册

依然问题跟上面一样,只不过这次多计算了2位,计算到29位以后,程序就不计算了,总是输出0
2013-08-10 01:34
歌舞伎町
Rank: 2
等 级:论坛游民
帖 子:30
专家分:38
注 册:2013-8-7
收藏
得分:0 
刚才利用F10查看了一下运行过程中的i和a的值的变化,发现问题在这里

就是i=9的时候,这时候a=a-1这一句中,本来a是1.200000,执行这一句减去1的操作后,结果a就变成了0.200001……

然后后面那个尾数小数就不停地变大变大再变大,最后直到a的值变成0.8125了……这个数字进行乘2取整,显然可以乘尽的……

这个是编译器自带的精度问题么?如果是,那么怎样才能避免这种情况发生呢?求助各位高手……多谢……分不多,见谅!
2013-08-10 02:12
love云彩
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:青藏高原
等 级:贵宾
威 望:53
帖 子:3663
专家分:11416
注 册:2012-11-17
收藏
得分:3 
有精度问题的存在,深夜了,明天再解答

思考赐予新生,时间在于定义
2013-08-10 02:18
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:3 
程序代码:
#include <stdio.h>

int a,b;

void print1(int a)
{
     if (a==0) return;
     print1(a/2);
     printf("%d",a%2);
}

void print2(int b)
{
     int i=b,j=1,step=0;
     while (j<=b) j*=10;
     while (step<30 && i>0)  //如果无限循环则输出前30位 
     {
           i=i+i;
           if (i>=j) printf("1"); else printf("0");
           i%=j;
           step++;
     }
}

int main()
{
    scanf("%d.%d",&a,&b);
    if (a==0) printf("0"); else print1(a);   //输出整数段 
    printf(".");
    if (b==0) printf("0"); else print2(b);   //输出小数段 
    printf("\n");
    
    system("pause");
}
    
2013-08-10 02:50
歌舞伎町
Rank: 2
等 级:论坛游民
帖 子:30
专家分:38
注 册:2013-8-7
收藏
得分:0 
回复 4楼 love云彩
是的,我也考虑过有可能是这个问题

我自己觉得,可能是这个原因,比如0.1,实际上是一个无限循环的二进制数字序列,但是存入内存中的值总是存在一定的长度,无论是32还是64,这也意味着,这个数字并不是真正的0.1,(假定它是0.999……5),但是不管怎样,既然这个数字是长度一定的二进制序列,那么它采用乘2取整的方式转换为二进制是可以完全转换的

所以在我的例子中,可能进行到第27步的时候,它就已经完全转换了,所以后面就全部是0了

不知道是不是这样?期待解答……
2013-08-10 06:51
歌舞伎町
Rank: 2
等 级:论坛游民
帖 子:30
专家分:38
注 册:2013-8-7
收藏
得分:0 
回复 5楼 czz5242199
你的代码我再仔细看看先
2013-08-10 06:56
XiaoXiao_Ren
Rank: 3Rank: 3
来 自:西安
等 级:论坛游侠
威 望:1
帖 子:80
专家分:198
注 册:2013-7-17
收藏
得分:3 
回复 5楼 czz5242199
void print2(int b)  
 //这个也不正确, 当输入数是0.01的时候,该b的取值是1, 那么输入数0.1或者0.01或者0.0001的结果都一样了。

否极泰来
2013-08-10 16:10
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 8楼 XiaoXiao_Ren
忘记考虑前导0了
程序代码:
#include <stdio.h>

int a;

void print1(int a)
{
     if (a==0) return;
     print1(a/2);
     printf("%d",a%2);
}

void print2()
{
     char s[100];
     int i,j=1,step=0,k=0;
     scanf(".%s",s);
     while (s[k]=='0') k++;
     if (s[k]==0)
     {
                 printf("0"); return;
     }
     sscanf(s+k,"%d",&i);
     while (j<=i) j*=10;
     while (k--) j*=10;
     while (step<=30 && i>0)
     {
           i=i+i;
           if (i>=j) printf("1"); else printf("0");
           i%=j;
           step++;
     }
}

int main()
{
    scanf("%d",&a);
    if (a==0) printf("0"); else print1(a);   //输出整数段 
    printf(".");
    print2();   //输出小数段 
    printf("\n");
    
    system("pause");
}
    
2013-08-10 17:11
小小程序猿
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:1
帖 子:755
专家分:2785
注 册:2013-7-18
收藏
得分:3 
不明觉厉

孤独与寂寞是催化一个人迅速成长的良药,没有之一
2013-08-10 17:49
快速回复:关于将小数转成二进制的问题,输入0.1结果不对,求高手指教!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.029680 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved