搜索
bottom↓
回复: 37

求绝世高手帮忙简化几行C语言代码

[复制链接]

出0入0汤圆

发表于 2010-9-14 16:14:24 | 显示全部楼层 |阅读模式
要d的值,计算一次要2900次,太长了,求绝世高手帮忙.

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000;
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--)
{
b=(g+c)/a;
c=g%a;
d=d+b;
}

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

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

出0入0汤圆

发表于 2010-9-14 16:22:34 | 显示全部楼层
程序有点问题吧,c没初始化就用?

出0入0汤圆

发表于 2010-9-14 16:25:27 | 显示全部楼层
c=g%e; 这句是定值就不用放在for里面吧?

出0入0汤圆

 楼主| 发表于 2010-9-14 16:26:17 | 显示全部楼层
我是用来计算梯形减速时 减速阶段产生的脉冲数。

出0入0汤圆

发表于 2010-9-14 16:28:09 | 显示全部楼层
b=g/e,因为g%e/e=0
如果其作初值为0的话
d+=b*2900/e
如果收到费用的话会讲的更详细点。(^_^)

出0入0汤圆

 楼主| 发表于 2010-9-14 16:52:47 | 显示全部楼层
哈 我写错了

uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--)
{
b=(g+c)/a;
c=g%a;
d=d+b;
}

出0入0汤圆

发表于 2010-9-14 17:00:02 | 显示全部楼层
优化:
uint16 d = 5189;

出0入0汤圆

 楼主| 发表于 2010-9-14 17:06:10 | 显示全部楼层
回复【7楼】helloshi
-----------------------------------------------------------------------

开始写错了 改了 值是6910

出0入0汤圆

发表于 2010-9-14 18:01:48 | 显示全部楼层
5楼应该是对的,不过第三行看不懂哈哈,再研究


晕晕我的结果不对, 发现这个b=(g+c)/a;   g+c不能拆开除,因为是整除


g=5 c=5 a=6

这样 b=(5+5)/6=1;

而拆后 b=g/a+c/a=5/6+5/6=0 ...

出0入0汤圆

发表于 2010-9-14 18:18:02 | 显示全部楼层
uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000;
a=0;b=0,c=0,d=0;

for(a=e;a>f;a--) //a等于3000(初始值),a如果大于100,执行下面语句后 a--
{
b=(g+c)/a;  //b=(2000+c)/a
c=g%a;      //c=2000%a
d=d+b;      //d=d+b
}

出0入0汤圆

发表于 2010-9-14 18:45:12 | 显示全部楼层
你这个需要从算法的层次好好重新规划一下,感觉是可以吧复杂度降到O(0)的

出0入0汤圆

发表于 2010-9-14 18:49:59 | 显示全部楼层
普通高手,旁观。

出0入0汤圆

发表于 2010-9-14 19:01:09 | 显示全部楼层
与CPLD FPGA有啥关系?

出0入0汤圆

发表于 2010-9-14 20:32:59 | 显示全部楼层
【11楼】 whyjld

弱问复杂度O(0)是什么概念?再低也只能是O(1)吧?

出0入0汤圆

发表于 2010-9-14 21:50:00 | 显示全部楼层
VHDL 做梯形加减速,你想复杂了。我曾发过几篇台湾和国外的文章,现在怎么找不到了

出0入0汤圆

发表于 2010-9-14 22:46:58 | 显示全部楼层
这个变量名和 ida 反编译出来的还难懂

出0入0汤圆

 楼主| 发表于 2010-9-15 08:57:16 | 显示全部楼层
回复【15楼】semonpic
-----------------------------------------------------------------------

经验不够 真心求教

就是运动控制的电机缓冲阶段 P从工作速度A降到另一速度B. P的脉冲数量,A,B和A降到B的时间可以自由设定.


在电机停时速度刚好到B,不能偏差太多. 也就是说要先知道什么时候开始减速.

现我能算出减速的位置,效果也相当理想.就是计算花的时间太长了.

出0入4汤圆

发表于 2010-9-15 09:08:49 | 显示全部楼层
一般高手,LOOK,LOOK.

出0入0汤圆

发表于 2010-9-15 09:53:53 | 显示全部楼层
回复【14楼】minux  啊啊?
-----------------------------------------------------------------------

不好意思,个人的错误习惯。
用的时候都是n的怎么怎么样,所以经常把n去掉,1是N的0次方,时间长了O(1)就用成O(0)了,纯属个人习惯,不好意思。

出0入0汤圆

 楼主| 发表于 2010-9-15 17:17:36 | 显示全部楼层
问题还没解决DDDDD

出0入0汤圆

发表于 2010-9-15 22:51:36 | 显示全部楼层
有问题,删了,下面是没问题的。

出0入0汤圆

发表于 2010-9-15 22:58:08 | 显示全部楼层
回复【17楼】40130064  
回复【15楼】semonpic 
-----------------------------------------------------------------------

经验不够 真心求教

就是运动控制的电机缓冲阶段 p从工作速度a降到另一速度b. p的脉冲数量,a,b和a降到b的时间可以自由设定.


在电机停时速度刚好到b,不能偏差太多. 也就是说要先知道什么时候开始减速.

现我能算出减速的位置,效果也相当理想.就是计算花的时间太长了.
-----------------------------------------------------------------------

只是梯形的话,只要每个周期都按照等差数列公式来算一下应不应该开始变速就好了

出0入0汤圆

发表于 2010-9-15 23:11:59 | 显示全部楼层
有问题,删了,下面是没问题的。

出0入0汤圆

发表于 2010-9-15 23:20:06 | 显示全部楼层
10MHz的AVR跑完这段要0.1秒。

出0入0汤圆

发表于 2010-9-16 00:11:02 | 显示全部楼层
你这个加减速是在单片机里做的还是在FPGA中作的,我的是放到FPGA中作的,如果做的是加减速对称的话,比较简单。可以参看MCX314的数据手册。
假设所需发送的脉冲数是N
在速度从VMIN 加到VMAX的过程过程中统计加速脉冲数A。已经发送的脉冲数是B 当N-B<=A时,既可以进行减速操作。在FPGA中就是几个加法器和比较器构成的。很简单。楼主可以测试测试

出0入0汤圆

发表于 2010-9-16 02:20:36 | 显示全部楼层
有问题,删了,下面是没问题的。

出0入0汤圆

发表于 2010-9-16 08:50:32 | 显示全部楼层
全部常数计算,直接一次计算好了放在RAM里面不行吗?

出0入0汤圆

 楼主| 发表于 2010-9-16 08:51:37 | 显示全部楼层
多谢各位,特别感谢HSZTC.

出0入0汤圆

发表于 2010-9-16 09:30:54 | 显示全部楼层
AT官方有个App,专门讲了梯形算法,楼主可参考下

出0入0汤圆

发表于 2010-9-16 10:43:15 | 显示全部楼层
既然初始值给定,循环次数就不会减少,考虑怎么讲循环体简化一下,貌似循环体中有一句c=g%a会浪费很多计算时间,可以单独提出来,值用另一个变量保存,使用时调用变量即可,通常%运算会浪费大量的运算时间。至于别人使用双层循环,运算时间会升至O(N)的平方级,效率会更低。

出0入0汤圆

发表于 2010-9-16 19:23:13 | 显示全部楼层
【28楼】 40130064

不客气,互相学习下。原来写的太乱了,出了点小差错。

uint16 a,b,c,d,e,f,g;  
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;  

for(a=e;a>f;a--)  
{  
b=(g+c)/a;  
if(g<a) c=g; else if(g<(a+a)) c=g-a; else c=g%a;  
d+=b;  
}

终于知道错在哪了哈哈,这个是正确的,效率提高1/3的。

应该还有简化的空间,得慢慢想。

出0入0汤圆

发表于 2010-9-16 21:05:15 | 显示全部楼层
uint16 a,c,d,e,f,g;  
e=3100,f=110,g=2100; //这些值不是一定的,是我假设的.
a=0;c=0,d=0;  

for(a=e;a>f;a--)  
{            
if((g+c)>=a){if((g+c)<(a+a)) d++; else d+=(g+c)/a;}   
if(g<a) c=g; else if(g<(a+a)) c=g-a; else c=g%a;   
}

效率提高了1/2,多测试下。

出0入0汤圆

发表于 2010-9-16 21:20:14 | 显示全部楼层
只适合没有16位硬件除法的单片机,如果有16位或以上的硬件除法的话,那原来的不用改更快。

出0入0汤圆

发表于 2010-9-17 20:02:55 | 显示全部楼层
如果单片机有硬件除法:
uint16 a,b,c,d,e,f,g;
e=3000,f=100,g=2000; //这些值不是一定的,是我假设的.
a=0;b=0,c=0,d=0;


for(a=e;a>f;a--)
{
b=g/a;
b+=c/a;
c=g%a;
d=d+b;
}

一般来说,除法计算同时能得到余数

出0入0汤圆

 楼主| 发表于 2010-9-18 10:45:39 | 显示全部楼层
看来只能放弃了 采用31楼方法 在ARM7内核下大概是30ms 如果说超过20ms 程序就跑不对.郁闷啊.

出0入0汤圆

发表于 2010-9-18 12:47:22 | 显示全部楼层
T曲线变速根本不用这样算啊
每周期算一次以下的东西,看看S是否大于(目标位置-当前位置)即可:
(Vt^2-Vo^2)/2a=S
Vt目标速度  Vo当前速度 a加速度 S匀加速运动经过的距离


S小于(目标位置-当前位置),即不需要减速,这个周期继续匀速
到了S 大于等于(目标位置-当前位置)的那个周期,则这个周期开始匀减速,这样到了目标位置的时候速度就能刚好是目标速度

出0入0汤圆

发表于 2010-9-18 21:16:34 | 显示全部楼层
32位的啊...


我都是在8位机上测试的,32位的话,数据类型定义为32位的会比16位的快,用 unsigned int


ARM7上有硬件除法吗? CM3上有硬件除法,不用优化都算的更快。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-24 17:25

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

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