打印

c51怎么把浮点数(精确0.1)小数位分离出来?这样可行?

[复制链接]
8648|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangzk|  楼主 | 2010-7-7 10:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wangzk 于 2010-7-7 11:02 编辑

菜鸟让大家见笑了  

aver_de   存储浮点数
aver_b     存  百位数字
aver_c     存  十位数字
aver_d    存   个位数字
aver_e   存     小数点
void  seperat(float   aver_de)
{
      uint   temp;
     temp=  aver_de*10;/////关键是这句
     aver_b= temp/1000 ; ////分离百位
      temp  = temp%1000 ;
     aver_c= temp/100; ////分离十位
     temp  = temp%100;
      aver_d= temp/10; ////分离个位
     temp  = temp%10;
     aver_e= temp   ;////分离小数位
     disp_engc();  ///////显示程序
}

实验结果是个十百位显示正常,但小数位显示不出来。还有如果想实现科学四舍五入那得把0.01分离出来?那大家有什么好的思路?

相关帖子

沙发
zq1987731| | 2010-7-7 11:13 | 只看该作者
既然都上浮点型计算了,还不如直接交给库,用stdio.h中的sprintf,以%X.Xf格式输出到你指定的数组中

使用特权

评论回复
板凳
wangzk|  楼主 | 2010-7-7 11:21 | 只看该作者
to  ls  :没用过库   sprintf还不会用  先找gugu

使用特权

评论回复
地板
ayb_ice| | 2010-7-7 11:21 | 只看该作者
可以
正确

使用特权

评论回复
5
一棵小草| | 2010-7-7 13:35 | 只看该作者
听那位前辈说过了,要尽量少用浮点数,特别KeilC中。
还有是看看C是怎么做运算的
temp=  aver_de*10;
整型 =  浮点  *    整型      是不是等价于    整型 = (整型)浮点   *    整型   (查书吧,我忘了)
不知道是不是我没记好,在运算过程中,浮点被强制转换成整型了,就是说,小数点不参与乘法。
temp=  aver_de*10.0;改成这样行不行?

如果要四舍五入的话,得分离2个小数来判断吧,方法一样。

使用特权

评论回复
6
ayb_ice| | 2010-7-7 13:43 | 只看该作者
LS
aver_de本身就是浮点数
...

使用特权

评论回复
7
wangzk|  楼主 | 2010-7-7 14:13 | 只看该作者
to  2lou:用 sprintf   感觉还不如自己写函数 分离各位  数

to  5lou:没办法啊   必须要浮点数

使用特权

评论回复
8
zjswuyunbo| | 2010-7-7 14:47 | 只看该作者
看起来,没啥问题啊

使用特权

评论回复
9
zq1987731| | 2010-7-7 14:54 | 只看该作者
如果你自己写的分离函数,效率及可靠性等等问题处理得都比库强,那最好,不然:
float x = 123.4;
UINT8 tmp[10];
sprintf(tmp, "%4.1f", x);
执行完后tmp[0]~tmp[4]的内容即'1','2','3','.','4'

使用特权

评论回复
10
wangzk|  楼主 | 2010-7-7 15:34 | 只看该作者
显示正常   问题解决   :)

使用特权

评论回复
11
batsong| | 2010-7-7 15:52 | 只看该作者
在C++里,实数(float)是用四个字节即三十二位二进制位来存储的。其中
有1位符号位,8位指数位和23位有效数字位。实际上有效数字位是24位,因为第
一位有效数字总是“1”,不必存储。
    有效数字位是一个二进制纯小数。8位指数位中第一位是符号位,这符号位和
一般的符号位不同,它用“1”代表正,用”0“代表负。整个实数的符号位用“
1”代表负,“0”代表正。
    在这存储实数的四个字节中,将最高地址字节的最高位编号为31,最低地址
字节的最低位编号为0,则实数各个部分在这32个二进制位中的分布是这样的:3
1位是实数符号位,30位是指数符号位,29---23是指数位,22---0位是有效数字
位。注意第一位有效数字是不出现在内存中的,它总是“1”。
     
    将一个实数转化为C++实数存储格式的步骤为:
    (1)先将这个实数的绝对值化为二进制格式,注意实数的整数部分和小数部
分化为二进制的方法是不同的。
    (2)将这个二进制格式实数的小数点左移或右移n位,直到小数点移动到第
一个有效数字的右边。
    (3)从小数点右边第一位开始数出二十三位数字放入第22到第0位。
    (4)如果实数是正的,则在第31位放入“0”,否则放入“1”。
    (5)如果n 是左移得到的,说明指数是正的,第30位放入“1”。如果n是右
移得到的或n=0,则第30位放入“0”。
    (6)如果n是左移得到的,则将n减去一然后化为二进制,并在左边加“0”
补足七位,放入第29到第23位。如果n是右移得到的或n=0,则将n化为二进制后在
左边加“0”补足七位,再各位求反,再放入第29到第23位。
     
    将一个计算机里存储的实数格式转化为通常的十进制的格式的方法如下:
    (1)将第22位到第0位的二进制数写出来,在最左边补一位“1”,得到二十
四位有效数字。将小数点点在最左边那个“1”的右边。
    (2)取出第29到第23位所表示的值n。当30位是“0”时将n各位求反。当30
位是“1”时将n增1。
    (3)将小数点左移n位(当30位是“0”时)或右移n位(当30位是“1”时)
,得到一个二进制表示的实数。
    (4)将这个二进制实数化为十进制,并根据第31位是“0”还是“1”加上正
号或负号即可。

    特别地,实数0用C++的float格式表示是0000000000000000000000000000000
0。
     
    如果还不太明白,这里举几个例子。
    一。将23.56化为C++的float格式。
    (1)将23.56化为二进制后大约是“10111.1000111101011100001”。
    (2)将小数点左移四位,得到“1.01111000111101011100001”。
    (3)这已经有了二十四位有效数字,将最左边一位“1”去掉,得到“0111
1000111101011100001”。将它放入第22到第0位。
    (4)因为23.56是正数,因此在第31位放入“1”。
    (5)由于我们把小数点左移,因此在第30位放入“1”。
    (6)因为我们是把小数点左移4位,因此将4减去1得3,化为二进制,并补足
七位得到0000011,放入第29到第23位。
    完毕。
    如果把最左边定为第31位,最右边定为第0位,那么在C++里,float格式的2
3.56是这样表示的:01000001101111000111101011100001。相应地-23.56就是这
样表示的:11000001101111000111101011100001。

    二。将实数0.2356化为C++的float格式。
    (1)将0.2356化为二进制后大约是0.00111100010100000100100000。
    (2)将小数点右移三位得到1.11100010100000100100000。
    (3)从小数点右边数出二十三位有效数字,即11100010100000100100000放
入第22到第0位。
    (4)由于0.2356是正的,所以在第31位放入“0”。
    (5)由于我们把小数点右移了,所以在第30位放入“0”。
    (6)因为小数点被右移了3位,所以将3化为二进制,在左边补“0”补足七
位,得到0000011,各位取反,得到1111100,放入第29到第23位。
    完毕。因此0.2356用C++的float格式表示是:00111110011100010100000100
100000。其中最左边一位是第31位,最右边一位是第0位。

    三。将实数1.0化为C++的float格式。
    (1)将1.0化为二进制后是1.00000000000000000000000。
    (2)这时不用移动小数点了,这就是我们在转化方法里说的n=0的情况。
    (3)将小数点右边的二十三位有效数字00000000000000000000000放入第22
到第0位。
    (4)因为1.0是正的,所以在第31位里放入“0”。
    (5)因为n=0,所以在第30位里放入“0”。
    (6)因为n=0,所以将0补足七位得到0000000,各位求反得到1111111,放入
第29到第23位。
    完毕。所以实数1.0用C++的float格式表示是:0011111110000000000000000
0000000。其中最左边一位是第31位,最右边一位是第0位。




    这是IEEE短实数格式,适合X86cpu。

使用特权

评论回复
12
batsong| | 2010-7-7 15:53 | 只看该作者
看完上面的,可以手动解决

使用特权

评论回复
13
linqing171| | 2010-7-7 18:04 | 只看该作者
楼主做法太弯路了。
去下个浮点汇编库看看,很简单的。

先取阶数,看看整数部分有多少位,如果有正的位数,直接移动出来就是了。

使用特权

评论回复
14
linqing171| | 2010-7-7 18:05 | 只看该作者
不知道下面代码可以不。
float f=3.14159;
f=f-(long)f;

使用特权

评论回复
15
李冬发| | 2010-7-7 18:08 | 只看该作者
在MCU里哪里非需要浮点不可啊?
完全可以用长整型代替。不过长整型运算也是比较慢的。

使用特权

评论回复
16
tianya1977| | 2010-7-7 20:25 | 只看该作者
把浮点数赋值给整型变量会去掉该数的小数部分.

使用特权

评论回复
17
jack.king| | 2010-7-7 22:15 | 只看该作者
在温度采集的时候用float类型的吧!
还是采用别的方法呢!

使用特权

评论回复
18
linqing171| | 2010-7-8 08:11 | 只看该作者
温度一直用定点的,最低位代表1/256℃。最高位是符号位,测量范围和精度都可以保证。

使用特权

评论回复
19
kevinryliu| | 2010-7-8 09:41 | 只看该作者
没文化不懂C,学习了……

使用特权

评论回复
20
jack.king| | 2010-7-8 09:47 | 只看该作者
18L :定点??

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:[url=http://huiqianxi.taobao.com]http://huiqianxi.

91

主题

680

帖子

0

粉丝