搜索
bottom↓
回复: 13

求教float运算, 怎么这么怪呢....

[复制链接]

出0入0汤圆

发表于 2012-4-13 21:49:39 | 显示全部楼层 |阅读模式
求教大家,计算时,按方法一,可以得到想要的结果,如果合起来写,得到的结果不对,,,,,,是为什么啊.....
方法一:

        fTmpCcr = (float)g_ilCalResult[CFlashData.CPwm.m_ucChnnl[i]]*(float)CFlashData.CPwm.m_unFullXs[i];
          fTmpCcr /=(float)CFlashData.CPwm.m_ucRang[i]*g_ilPwmOutUe[CFlashData.CInputPara.m_ucVolUe]*0.01;
            fTmpCcr += (float)CFlashData.CPwm.m_unZeroXs[i];

方法二:
       fTmpCcr = (float)g_ilCalResult[CFlashData.CPwm.m_ucChnnl[i]]*(float)CFlashData.CPwm.m_unFullXs[i]
        /(float)CFlashData.CPwm.m_ucRang[i]*g_ilPwmOutUe[CFlashData.CInputPara.m_ucVolUe]*0.01 + (float)CFlashData.CPwm.m_unZeroXs[i];

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-4-13 21:56:29 | 显示全部楼层
您了是想累死单片机吗?
吧数据拆开了分别计算吧,可能会浪费点RAM,但是保证了计算的准确度。
同样的问题在整形计算的时候也遇见过。
因此采用分开计算。
具体愿意未知,猜想是单片机自身预算能力与编译软件在译码的时候出错了!

出0入0汤圆

 楼主| 发表于 2012-4-13 22:08:15 | 显示全部楼层
lvyunzeng 发表于 2012-4-13 21:56
您了是想累死单片机吗?
吧数据拆开了分别计算吧,可能会浪费点RAM,但是保证了计算的准确度。
同样的问题 ...

谢谢啊,那写flOAT运算语句一般写多长有没有规定啊。。。
写多长算长啊。。。。
3Q

出0入0汤圆

发表于 2012-4-13 23:41:03 | 显示全部楼层
没本事保证合起来运算顺序(优先级)正确就不要合起来写。
要么就多加几个括号。

分开写不代表就效率低, 合起来写也并不见得会效率高。
没人规定一行最多写多长,但一般终端只有80字符,所以很多软件在80字符处会有个细线。

其实,可以把整个源文件都写成一行(html代码里面经常有这么干的,省流量)。

出0入0汤圆

发表于 2012-4-13 23:42:42 | 显示全部楼层
优美的代码错落有致,你的代码不管方法一还是方法二,直接头晕。

出0入0汤圆

发表于 2012-4-13 23:51:04 | 显示全部楼层
本帖最后由 eduhf_123 于 2012-4-13 23:53 编辑

方法二的运算顺序变了:
fTmpCcr = (float)g_ilCalResult[CFlashData.CPwm.m_ucChnnl[ i ]]*(float)CFlashData.CPwm.m_unFullXs[ i ]
/((float)CFlashData.CPwm.m_ucRang[ i ]*g_ilPwmOutUe[CFlashData.CInputPara.m_ucVolUe]*0.01) + (float)CFlashData.CPwm.m_unZeroXs[ i ];

加上红色字标示的一对括号后,运算结果就能与方法一保持一致了。
或者可以不加括号,但需要把这对括号中的所有“*”改为“/”。
要知道,乘法的优先级并不比除法的高,它们是一致的,结合顺序是从左到右。

出0入0汤圆

 楼主| 发表于 2012-4-14 00:02:07 | 显示全部楼层
eduhf_123 发表于 2012-4-13 23:51
方法二的运算顺序变了:
fTmpCcr = (float)g_ilCalResult[CFlashData.CPwm.m_ucChnnl[ i ]]*(float)CFlashD ...

谢谢啊...
我先按你的方法试试看,
但在我看来,乘除谁先谁后不都是一样嘛......
为什么"/"后面的要加括号呢.

出0入0汤圆

 楼主| 发表于 2012-4-14 00:03:33 | 显示全部楼层
aozima 发表于 2012-4-13 23:42
优美的代码错落有致,你的代码不管方法一还是方法二,直接头晕。

呵呵
其实我的变量名称长点儿...
分开写的话就是完成加,减,乘,除之一啊....

出0入0汤圆

发表于 2012-4-14 00:32:59 | 显示全部楼层
ilikeavr666 发表于 2012-4-14 00:02
谢谢啊...
我先按你的方法试试看,
但在我看来,乘除谁先谁后不都是一样嘛......

a = 36;
a /= 2*3;
这里最后相当于a = 36/6 =6,也就是相当于a = 36/2/3 = (36/2)/3

但是如果你这样写:
a = 36/2*3
那就相当于a = (36/2)/*3了,最后的结果就不是6、而是54了。

出0入0汤圆

 楼主| 发表于 2012-4-14 01:10:46 | 显示全部楼层
eduhf_123 发表于 2012-4-14 00:32
a = 36;
a /= 2*3;
这里最后相当于a = 36/6 =6,也就是相当于a = 36/2/3 = (36/2)/3

eduhf_123
太感谢了....
原来式子写错了....
真的明白了,
呵呵................................
我还以为分开写和合起来不一起呢,.........

出0入0汤圆

发表于 2012-4-15 07:34:50 | 显示全部楼层
aozima 发表于 2012-4-13 23:41
没本事保证合起来运算顺序(优先级)正确就不要合起来写。
要么就多加几个括号。

此楼是正解!

出0入0汤圆

发表于 2012-4-15 07:46:57 | 显示全部楼层
让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪

出0入0汤圆

 楼主| 发表于 2012-4-15 10:31:35 | 显示全部楼层
liusoldier 发表于 2012-4-15 07:46
让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪 ...

谢谢啊,我试着改为整形计算看看.....

出0入0汤圆

 楼主| 发表于 2012-4-16 13:49:04 | 显示全部楼层
liusoldier 发表于 2012-4-15 07:46
让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪 ...

         你好,我这样子改结果也是对的,帮我看看,跟前面float计算哪个效率高啊.谢谢
    fTmpCcr = (int32)((int64)(g_ilCalResult[CFlashData.CPwm.m_ucChnnl]*((int64)CFlashData.CPwm.m_unFullXs)*100)
         /((int32)CFlashData.CPwm.m_ucRang*g_ilVoltageUe[CFlashData.CInputPara.m_ucVolUe]) + CFlashData.CPwm.m_unZeroXs);
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-28 12:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表