数值分析c语言程序,科学网—C语言数值计算版 - 王龙飞的博文

C/C++效率高,用来做系统底层的设计无疑是很好的,但是现在也有很多人用来做数值计算。

不过C/C++并没有为数值计算优化。最简单的,比如:幂函数居然要写成pow(x,n)这样比较复杂的形式,如果使用x^n更符合直觉,更易用;复杂一点的,Fortran里有对矩阵的操作块的操作,C/C++里只能一个数一个数地操作。

如果能做一个编译器级别的改变肯定是最好的,引入一些对于数值计算更易用的语法,再引入一些数值计算库,这样或许可以开发一个C/C++数值计算的变种。不过这个事笔者目前是没有这能力。如果有人有能力而且感兴趣,不妨建个开源项目什么的。

易学易用是重要的一方面,但是功能的强大、方便扩展无疑更重要。如果这个C/C++的分支相对于原始C/C++及其它科学计算语言来说没有很大的优势,肯定做不起来,不如不做!目前Fortran做数值计算就比C易学易用一些;科学计算的库,也已经有很多了,有类似matlab矩阵操作的库函数,有符号计算的库;matlab、mathematica这样的脚本语言很成熟,易用扩展性强;结合C和python脚本的scipy和numpy这样的科学计算平台做得也很好,用的人不少。

这里,笔者介绍一个自己做的小东西。不改变标准C语法,只是写程序的时候:用$表示标准C语言中的按位异或,用^表示乘方,然后在预处理的时候再转换回去。(这种事情意义不大,如果能成为标准才有意义)。

下面是把“x^n”转变成“pow(x,n)”的Perl脚本,考虑各种可能的情况:

最终版本如下:

#!/usr/bin/perl

my \$levelN = qr/ (?> [^()]+ | \( (??{ \$levelN }) \) )* /x;

while () {

(/\^/) while

s/(\w*\.*\w+|[pow]*\(\$levelN\))\s*\^\s*([pow]*\($levelN\)|\w+\.*\w*)/pow(\$1,\$2)/;

print "\$_";

}

用法cat filename.c | ./perfect new_filename.c

测试例子:

$ echo -e "a.b^(c+d)^(e-f/g^h*i)" | ./perfect

pow(pow(a.b,(c+d)),(e-f/pow(g,h)*i))

$ echo -e "^ (c+d) *^/ (e-f/g^h*i)" | ./perfect

^ (c+d) *^/ (e-f/pow(g,h)*i)

功能完整、不处理语法错误、健壮、很简洁。

默认a^b^c为(a^b)^c。

缺点:会有些非必要的括号。

最初的版本,加上规避a^b^c形式的功能,好处是具有去掉非必要括号功能,缺点是代码里面4种不同类型的字符替换代码重复度高、顺序不能变:

#!/usr/bin/perl

# dynamic regexp

my \$levelN = qr/ (?> [^()]+ | \( (??{ \$levelN }) \) )* /x;

# do the replacement and print to screen.

while(){

my \$line  = \$_;

my \$line1 = \$line;

if(/\^\s*\(\$levelN\)\s*\^/ | /\^\s*\w*\.*\w*\s*\^/){die "Error: Form 'A^B^C' is not allowed, please clarify it as '(A^B)^C' or 'A^(B^C)'!";}

while(1){

\$line1=~ s/\((\$levelN)\)\s*\^\s*\((\$levelN)\)/pow(\$1,\$2)/g; #(a+b)^(c+d)

if("\$line1" eq "\$line"){last;}

\$line=\$line1;

}

while(1){

\$line1=~ s/(\w*\.*\w+)\s*\^\s*\((\$levelN)\)/pow(\$1,\$2)/g; #a^(b+c)

if("\$line1" eq "\$line"){last;}

\$line=\$line1;

}

while(1){

\$line1=~ s/\((\$levelN)\)\s*\^\s*(\w+\.*\w*)/pow(\$1,\$2)/g; #(a+b)^c

if("\$line1" eq "\$line"){last;}

\$line=\$line1;

}

while(1){

\$line1=~ s/(\w*\.*\w+)\s*\^\s*(\w+\.*\w*)/pow(\$1,\$2)/g; #a^b

if("\$line1" eq "\$line"){last;}

\$line=\$line1;

}

print "\$line"

}

用法:./topow filename.c >newname.c

第一次写的perl脚本,边学边写的。

另外可以参考相关讨论和网友zhao4zhong1的C语言版本源代码:http://bbs.csdn.net/topics/390671469

转载本文请联系原作者获取授权,同时请注明本文来自王龙飞科学网博客。

链接地址:http://blog.sciencenet.cn/blog-335776-751582.html

上一篇:虚拟世界的电子云

下一篇:《计算机与人脑》笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值