| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1740 人关注过本帖
标题:把double类型转换成BCD链时出现问题
只看楼主 加入收藏
yyf8421bcd
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2017-1-22
结帖率:100%
收藏
已结贴  问题点数:14 回复次数:8 
把double类型转换成BCD链时出现问题
现有一c程序,作用是把整数部分为两位的double类型转化成定长BCD链
例如:
有一个 double 类型的数字是 2.87
相应的3位BCD链中的内容是 0X02,0X87,0X00

我写了一个转换函数如下:

unsigned char * Dou2BcdCh(double data,int len){
//将double类型转化为BCD链
//data待转换的double类型数据,它的整数部分最多两位,最少0位
//len BCD链的总长   
int i,k;   
int i,k;
unsigned char *Chain;
double temp=data;
int integer;   
printf("data is %lf \r\n",data);
Chain=(unsigned char*)malloc(
                len*sizeof(unsigned char)
               );
for(i=0;i<len;i++){
k=1;         
while(temp>=(double)(1.0)){
    temp=temp-(double)(1.0);
    printf("*****while*****%d\r\n",k);
    k++;
}
integer=data-temp;
printf("data is %lf,temp is %lf ,integer is %lf,%d\r\n",data,temp,integer,integer);
Chain[i]=Dec2Bcd(integer);//Dec2Bcd 将一个两位整数转化为相应的BCD码        
data=temp*(double)(100.0);
printf("data = %lf \r\n",data);
temp=data;           
printf("temp= %lf\r\n",temp);
}   
for(i=0;i<len;i++)
printf("0X%x ",Chain[i]);
printf("\r\n");
return Chain;
}

调试中出现的问题如下:
对于 输入2.87 正确的输出 应该为
0x2 0x87 0x00
实际上的输出却为
0x2 0x86 0x99

对于 输入 2.15 正确的输出 应该为
0x2 0x15 0x00
实际上的输出为
0x2 0x14 0x99

观察程序输出结果,感觉最有可能是while循环那里除了问题,
但是真实的原因是什么呢?解决方案是?
谢谢各位!

附:
1.
unsigned char Dec2Bcd(int dec)
{
    unsigned char bcd,high,low;
    high=dec/10;
    low=dec%10&0x0f;
    bcd=high<<4|low;
    return bcd;
}


搜索更多相关主题的帖子: double c程序 
2017-03-29 10:19
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:14 
这估计是dboule类型本身特性导致  你可以试着 让原始数据长些 比如2.872365

DO IT YOURSELF !
2017-03-29 10:29
yyf8421bcd
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2017-1-22
收藏
得分:0 
回复 2楼 wp231957
把原始数据从2.87换成2.8700确实可以
但是有没有其它办法,使得原始数据是2.87的时候仍旧可行?
2017-03-29 10:34
yyf8421bcd
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2017-1-22
收藏
得分:0 
回复 2楼 wp231957
原始数据是2.1500时 问题依旧出现
2017-03-29 10:36
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
这个浮点数据吧 比较特殊 、
就是不是“眼见为实”  比如 1.5 这只是我们看到的  实际肯能是1.499999999999也可能是1.5000000000001

所以要使用浮点数来做一些精确的事情  这个误差避免不了

我也想不到好办法  因为我不晓得你的浮点数据的来源

你可以试一下 把除法变成乘法  把小数变成整数 试一下

DO IT YOURSELF !
2017-03-29 10:41
yyf8421bcd
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2017-1-22
收藏
得分:0 
回复 5楼 wp231957
原始数据就是 直接写一个小数直接作参数

往原始数据上加一些东西就解决
比如
2.87 ,3写参数的时候写成2.870009,3就可以了
但是总感觉这样有很多隐患
2017-03-29 10:54
sharplong
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:122
专家分:121
注 册:2017-3-27
收藏
得分:0 
楼主,小白问个问题,什么是BCD链啊??

跟据科学研究呢,拥有一个良好的头像呢,有助于提高帖子关注度,和被友好对待的可能性:)准确来说呢,其实,我是一个演员....和兼职汽车维修员
2017-03-29 11:05
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9032
专家分:54066
注 册:2011-1-18
收藏
得分:0 
我怎么看不懂呀
程序代码:
#include <stdio.h>
#include <assert.h>

unsigned char* dbl2bcd( double data, unsigned char bcd[static 3] )
{
    assert( data>=0 && data<100 && data*10000+0.5<1000000 );

    long val = (long)( data*10000+0.5 );
    bcd[0] = (val/10000/10%10)*16 + (val/10000%10);
    bcd[1] = (val/100/10%10)*16 + (val/100%10);
    bcd[2] = (val/1/10%10)*16 + (val/1%10);

    return bcd;
}

void test( double data )
{
    unsigned char bcd[3];
    dbl2bcd( data, bcd );
    printf( "0x%02x 0x%02x 0x%02x\n", bcd[0], bcd[1], bcd[2] );
}

int main( void )
{
    test( 2.87 );
    test( 2.15 );
}

2017-03-29 11:10
初学编程的人
Rank: 2
等 级:论坛游民
威 望:2
帖 子:90
专家分:84
注 册:2017-3-12
收藏
得分:0 
看浮点数的设计规则就知道怎么回事了,浮点数是无法做到精确的,都有精度范围。转换成字符然后再处理估计好点。
2017-03-29 11:30
快速回复:把double类型转换成BCD链时出现问题
数据加载中...
 
   



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

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