ilikeavr666 发表于 2012-4-13 21:49:39

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

求教大家,计算时,按方法一,可以得到想要的结果,如果合起来写,得到的结果不对,,,,,,是为什么啊.....
方法一:

      fTmpCcr = (float)g_ilCalResult]*(float)CFlashData.CPwm.m_unFullXs;
          fTmpCcr /=(float)CFlashData.CPwm.m_ucRang*g_ilPwmOutUe*0.01;
            fTmpCcr += (float)CFlashData.CPwm.m_unZeroXs;

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

lvyunzeng 发表于 2012-4-13 21:56:29

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

ilikeavr666 发表于 2012-4-13 22:08:15

lvyunzeng 发表于 2012-4-13 21:56 static/image/common/back.gif
您了是想累死单片机吗?
吧数据拆开了分别计算吧,可能会浪费点RAM,但是保证了计算的准确度。
同样的问题 ...

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

aozima 发表于 2012-4-13 23:41:03

没本事保证合起来运算顺序(优先级)正确就不要合起来写。
要么就多加几个括号。

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

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

aozima 发表于 2012-4-13 23:42:42

优美的代码错落有致,你的代码不管方法一还是方法二,直接头晕。

eduhf_123 发表于 2012-4-13 23:51:04

本帖最后由 eduhf_123 于 2012-4-13 23:53 编辑

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

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

ilikeavr666 发表于 2012-4-14 00:02:07

eduhf_123 发表于 2012-4-13 23:51 static/image/common/back.gif
方法二的运算顺序变了:
fTmpCcr = (float)g_ilCalResult]*(float)CFlashD ...

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

ilikeavr666 发表于 2012-4-14 00:03:33

aozima 发表于 2012-4-13 23:42 static/image/common/back.gif
优美的代码错落有致,你的代码不管方法一还是方法二,直接头晕。

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

eduhf_123 发表于 2012-4-14 00:32:59

ilikeavr666 发表于 2012-4-14 00:02 static/image/common/back.gif
谢谢啊...
我先按你的方法试试看,
但在我看来,乘除谁先谁后不都是一样嘛......


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了。

ilikeavr666 发表于 2012-4-14 01:10:46

eduhf_123 发表于 2012-4-14 00:32 static/image/common/back.gif
a = 36;
a /= 2*3;
这里最后相当于a = 36/6 =6,也就是相当于a = 36/2/3 = (36/2)/3


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

lvyunzeng 发表于 2012-4-15 07:34:50

aozima 发表于 2012-4-13 23:41 static/image/common/back.gif
没本事保证合起来运算顺序(优先级)正确就不要合起来写。
要么就多加几个括号。



此楼是正解!

liusoldier 发表于 2012-4-15 07:46:57

让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪

ilikeavr666 发表于 2012-4-15 10:31:35

liusoldier 发表于 2012-4-15 07:46 static/image/common/back.gif
让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪 ...

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

ilikeavr666 发表于 2012-4-16 13:49:04

liusoldier 发表于 2012-4-15 07:46 static/image/common/back.gif
让单片机去float,又费资源,又耗时钟周期!我在Atmega8上试过简单的浮点运算,生成的代码量惊人哪 ...

         你好,我这样子改结果也是对的,帮我看看,跟前面float计算哪个效率高啊.谢谢
    fTmpCcr = (int32)((int64)(g_ilCalResult]*((int64)CFlashData.CPwm.m_unFullXs)*100)
         /((int32)CFlashData.CPwm.m_ucRang*g_ilVoltageUe) + CFlashData.CPwm.m_unZeroXs);
页: [1]
查看完整版本: 求教float运算, 怎么这么怪呢....