博文

破解求pi的怪异程序(2006-08-05 01:14:00)

摘要:Cong Wang25th November,2005Institute of Post and Telecommunication, Xi'an, PRC ChinaNetwork Engineering Dep.引言  网上流传着一个怪异的求pi程序,虽然只有三行却能求出pi值连小数点前共800位。这个程序如下:/*某年Obfuscated C Contest佳作选录:*/ #include < stdio.h>long a=10000, b, c=2800, d, e, f[2801], g; main(){for(;b-c;)f[b++]=a/5; for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a) for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b);} /* (本程式可算出pi值连小数点前共800位) (本程式录自sci.math FAQ,原作者未详)*/ 咋一看,这程序还挺吓人的。别慌,下面就告诉你它是如何做到的,并且告诉你写怪异C程序的一些技巧。^_^展开化简  我们知道,在C语言中,for循环和while循环可以互相代替。  for(statement1;statement2;statement3){    statements;  }上面的for语句可以用下面的while语句来代替:  statement1;  while(statement2){    statements;    statement3;  }而且要写怪异的C程序,逗号运算符无疑是一个好的助手,它的作用是: 从左到右依次计算各个表达式的值,并且返回最右边表达式的值。把它嵌入for循环中是写怪异代码的常用技巧之一。所以,上面的程序可以展开为: #include < stdio.h> /*1*//*2*/long a=10000, b, c=2800, d, e, f[2801], g; /*3*/main(){ /*4*/  while(b-c!=0){ /*5*/    f[b]=a/5; /*6*/  ......

阅读全文(4782) | 评论:1

软考常用算法设计方法(一)(2006-08-04 00:17:00)

摘要:要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。算法数据结构是程序的两个重要方面。   算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。指令正确地描述了要完成的任务和它们被执行的顺序。计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。   通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。其次是算法所需要的存储空间少和执行更快等。   算法设计是一件非常困难的工作,经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。另外,为了更简洁的形式设计和藐视算法,在算法设计时又常常采用递归技术,用递归描述算法。   一、迭代法   迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:   (1) 选一个方程的近似根,赋给变量x0;   (2) 将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;   (3) 当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。   若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为:   【算法】迭代法求方程的根   { x0=初始近似根;    do {    x1=x0;    x0=g(x1); /*按特定的方程计算新的近似根*/    } while ( fabs(x0-x1)>Epsilon);    printf(“方程的近似根是%f ”,x0);   }   迭代算法也常用于求方程组的根,令    X=(x0,x1,…,xn-1)   设方程组为:    xi=gi(X) (I=0,1,…,n-1)   则求方程组根的迭代算法可描述如下:   【算法】迭代法求方程组的根    { for (i=0;i   x[i]=初始近似根;    do { ......

阅读全文(4323) | 评论:2

软件水平考试常用算法设计方法 (2006-06-05 01:33:00)

摘要:软件水平考试常用算法设计方法   要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。算法数据结构是程序的两个重要方面。   算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。指令正确地描述了要完成的任务和它们被执行的顺序。计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。   通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。其次是算法所需要的存储空间少和执行更快等。   算法设计是一件非常困难的工作,经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。另外,为了更简洁的形式设计和藐视算法,在算法设计时又常常采用递归技术,用递归描述算法。      一、迭代法   迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:  (1) 选一个方程的近似根,赋给变量x0;  (2) 将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;  (3) 当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。  若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为:  【算法】迭代法求方程的根  { x0=初始近似根;   do {   x1=x0;   x0=g(x1); /*按特定的方程计算新的近似根*/   } while ( fabs(x0-x1)>Epsilon);   printf(“方程的近似根是%f\n”,x0);  }  迭代算法也常用于求方程组的根,令   X=(x0,x1,…,xn-1)  设方程组为:   xi=gi(X) (I=0,1,…,n-1)  则求方程组根的迭代算法可描述如下:  【算法】迭代法求方程组的根   ......

阅读全文(4475) | 评论:1

比较典型的PID处理程序(2006-05-05 16:10:00)

摘要: 比较典型的PID处理程序 [日期:2005-2-1] 来源:21ICbbs 作者:lookuper [字体:大中小]/*====================================================================================================这是一个比较典型的PID处理程序,在使用单片机作为控制cpu时,请稍作简化,具体的PID参数必须由具体对象通过实验确定。由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的“余数”,做好余数补偿。这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。=====================================================================================================*/#include#include/*====================================================================================================PID FunctionThe PID (比例、积分、微分) function is used in mainlycontrol applications. PIDCalc performs one iteration of the PIDalgorithm.While the PID function works, main is just a dummy program showinga typical usage.=====================......

阅读全文(5578) | 评论:2

增量式PID控制算法程序(2006-05-05 16:09:00)

摘要:;********增量式PID控制算法程序***********;T、TD、TI、KP依次从30H,33H,36H,39H开始。;A,B,C的值依次存在BLOCK1,BLOCK2,BLOCK3的地址里; 这里R(k)给的是定值;ORG 0000HBLOCK1 EQU 43H ;A,B ,CBLOCK2 EQU 46HBLOCK3 EQU 49HUK EQU 4CH ;存结果UKRK EQU 50HEK EQU 53H ;存放偏差值E(k)的始址EK1 EQU 56H ;存放E(k-1)的始址EK2 EQU 59H ;存放E(k-2)的始址CK EQU 5CH ;采样数据始址BUFF EQU 60H ;暂存区BUFF1 EQU 63HBUFF2 EQU 66HREC EQU 69HTEST:MOV RK,#01H ;常数Rk的BCD码浮点数MOV RK+1,#12H ;1.25MOV RK+2,#50HMOV 3CH,#01H ;常数1的BCD码浮点数MOV 3DH,#10HMOV 3EH,#00HMOV 40H,#01H ;常数2的BCD码浮点数MOV 41H,#20HMOV 42H,#00HMOV 30H,#01H ;T的BCD 码浮点数MOV 31H,#23H ;2.34MOV 32H,#40HMOV 33H,#01H ;Td的BCD码浮点数MOV 34H,#35H ;3.54MOV 35H,#40HMOV 36H,#01H ;Ti的BCD码浮点数MOV 37H,#11H ;1.12MOV 38H,#20HMOV 39H,#01H ;Kp的BCD码浮点数MOV 3AH,#12H ;1.25MOV 3BH,#50HMOV R0,#RK ;指向BCD码浮点操作数LCALL BTOF ;将其转换成二进制浮点操作数MOV R0,#3CHLCALL BTOFMOV R0,#40HLCALL BTOFMOV R0,#39HLCALL BTOFMOV R0,#36H ;指向BCD码浮点操作数TiLCALL BTOF ;将其转换成二进制浮点操作数MOV R0,#33H ;指向BCD码浮点操作数TdLCALL BTOF ;将其转换成二进制浮点操作数MOV R0,#30H ;指向BCD码浮点操作数TLCALL BTOF ;将其转换成二进制浮点操作数MOV R1, #BUFF1 ;保......

阅读全文(6660) | 评论:2

积分分离PID控制算法程序 c51(2006-05-05 16:06:00)

摘要:;**********P10,积分分离PID控制算法程序 ********;T、TD、TI、KP依次从30H,33H,36H,39H开始。;A,B,C,A',的值依次存在BLOCK1,BLOCK2,BLOCK3 BLOCK4 的地址里;这里B'与C值相同; 这里R(k)给的是定值ORG 0000HE EQU 20H ; 一阈值GK EQU 23H ;G(k)GK1 EQU 26H ;G(k-1)FK EQU 29H ;F(k)FK1 EQU 2CH ;F(k-1)BLOCK1 EQU 50H ;ABLOCK2 EQU 53H ;BBLOCK3 EQU 56H ;CBLOCK4 EQU 5AH ;A'UK EQU 5DH ;存放结果BUFF EQU 43H ;暂存区BUFF1 EQU 46HBUFF2 EQU 49HBUFFR0 EQU 4CHREC EQU 63H ;采样次数RK EQU 66H ;R(k)CK EQU 69H ;采样数据始址EK EQU 6CH ;存放偏差值E(k)的始址EK1 EQU 70H ;存放E(k-1)的始址TEST: MOV RK,#01H ;常数Rk 1.25的BCD码浮点数MOV RK+1,#12HMOV RK+2,#50H; MOV E,#7EH ;设定一阈值0.001的BCD码浮点数; MOV E+1,#10H; MOV E+2,#00HMOV E,#00H ;阈值为0.3MOV E+1,#30HMOV E+2,#00HMOV 3CH,#01H ;常数1的BCD码浮点数MOV 3DH,#10HMOV 3EH,#00HMOV 40H,#01H ;常数2的BCD码浮点数MOV 41H,#20HMOV 42H,#00HMOV 30H,#01H ;T 2.34的BCD 码浮点数MOV 31H,#23HMOV 32H,#40HMOV 33H,#01H ;Td 3.54的BCD码浮点数MOV 34H,#35HMOV 35H,#40HMOV 36H,#01H ;Ti 1.12的BCD码浮点数MOV 37H,#11HMOV 38H,#20HMOV 39H,#01H ;Kp 1.25的BCD码浮点数MOV 3AH,#12HMOV 3BH,#50HMOV R0,#E ; 将其转换成二进制浮点操作数LCALL BTOFMOV R0,#RKLCALL ......

阅读全文(7359) | 评论:0

标准的PID处理例程 c(2006-05-05 16:04:00)

摘要: 标准的PID处理例程 /*====================================================================================================    这是从网上找来的一个比较典型的PID处理程序,在使用单片机作为控制cpu时,请稍作简化,具体的PID参数必须由具体对象通过实验确定。由于单片机的处理速度和ram资源的限制,一般不采用浮点数运算,而将所有参数全部用整数,运算到最后再除以一个2的N次方数据(相当于移位),作类似定点数运算,可大大提高运算速度,根据控制精度的不同要求,当精度要求很高时,注意保留移位引起的“余数”,做好余数补偿。这个程序只是一般常用pid算法的基本架构,没有包含输入输出处理部分。=====================================================================================================*/#include <string.h>#include <stdio.h>/*====================================================================================================    PID Function        The PID (比例、积分、微分) function is used in mainly    control applications. PIDCalc performs one iteration of the PID    algorithm.    While the PID function works, main is just a dummy program showing    a typical usage.=====================================......

阅读全文(4129) | 评论:0

PID控制C源程序(2006-05-05 15:59:00)

摘要: PID控制C源程序   BC31 TC30 编译过,可运行。      #include <stdio.h>  #include<math.h>    struct _pid {   int pv; /*integer that contains the process value*/   int sp; /*integer that contains the set point*/   float integral;   float pgain;   float igain;   float dgain;   int deadband;   int last_error;  };    struct _pid warm,*pid;  int process_point, set_point,dead_band;   float p_gain, i_gain, d_gain, integral_val,new_integ;;         /*------------------------------------------------------------------------   pid_init     DESCRIPTION This function initializes the pointers in the _pid structure   to the process variable and the setpoint. *pv and *sp are   integer pointers.   ------------------------------------------------------------------------*/   void pid_init(struct _pid *warm, int process_point, int set_point)  {    struct _pid *pid;       pid = warm;    pid->pv = process_point;    pid->sp = set_point;   }       /*---------------------------------------------------......

阅读全文(8438) | 评论:4

PID算法  C51(2006-05-05 15:57:00)

摘要: 典型的PID处理程序(C51)(可改为061的) --  作者:mojixing--  发布时间:2004-8-25 17:06:00--  什么是PID算法啊? --  作者:robot4359--  发布时间:2004-8-25 17:30:00--   PID是比例、积分、微分三个词语的英文缩写,PID运算用于自动控制中。 当设定值和实际值不一样时,对误差进行PID运算,运算结果输入到执行器。 这里给的是数字PID运算。 详细的东西可以看一下自动化仪表中的控制器部分 --  作者:powerint--  发布时间:2004-8-30 21:08:00--   ;//**************************************************************************************************************;//功    能: 电机控制的PID(积分分离)  PID(void)    执行时间少于70uS/932-12MHz;//设 计 者: 牟联树;//日    期: 2003.12.28;//版 本 号: 1.0;//申    明: ;//**************************************************************************************************************$NOMOD51    OCRAH  equ 0EFh    OCRAL  equ 0EEh    OCRBH  equ 0FBh&n......

阅读全文(9760) | 评论:2

11种经典软件滤波的原理和实现(2006-05-05 12:16:00)

摘要: 1、限幅滤波法(又称程序判断滤波法)    A、方法:        根据经验判断,确定两次采样允许的最大偏差值(设为A)        每次检测到新值时判断:        如果本次值与上次值之差<=A,则本次值有效        如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值    B、优点:        能有效克服因偶然因素引起的脉冲干扰    C、缺点        无法抑制那种周期性的干扰        平滑度差    2、中位值滤波法    A、方法:        连续采样N次(N取奇数)        把N次采样值按大小排列        取中间值为本次有效值    B、优点:        能有效克服因偶然因素引起的波动干扰        对温度、液位的变化缓慢的被测参数有良好的滤波效果    C、缺点:        对流量、速度等快速变化的参数不宜3、算术平均滤波法    A、方法:        连续取N个采样值进行算术平均运算        N值较大时:信号平滑度较高,但灵敏度较低        N值较小时:信号平滑度较低,但灵敏度较高&nbs......

阅读全文(8980) | 评论:0