无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 8216|回复: 36
打印 上一主题 下一主题

[最终版,附源码]超小的数学表达式计算命令,可能大家有用得着的时候。

[复制链接]
跳转到指定楼层
1#
发表于 2010-11-11 23:06:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
理论上支持无穷表达式计算,支持错误表达式说明。
最终版对测试版的变化:
1、欧拉常数、圆周率由原来的函数形式引用改为常数形式引用,
    下面红字的示例是常量形式引用圆周率,最后面二幅图是原来的函数形式引用圆周率
2、小数点后最多可以输出16位,默认6位;
3、增加若干函数,对数函数由原来的两个增加到三个(注意参数的变化),见下面的列表;
4、无参数执行命令时,即会列出使用说明。

源码说明
因这类工具网上很多,也与论坛的已有工具部分功能重叠,所以这个工具不会再更新,
但附出源码,有兴趣的可以搞下去,只要在适当地方保留本人的信息就够了。
本人这个源码设计的架构相当先进,也有详细的注释,对数学表达式的解释思路也很明白,执行效率也不错,要扩展功能,
如添加新的数学常量、新的数学函数或新的自定义函数都相当容易,
在源码的头文件( CALC.H )开始处说明如何添加新的数学常量和新的数学函数。
源码特点:注释详细、思路清晰、扩展容易,可以计算无穷复杂的数学表达式。
CONST enum cConstIndex  //常量序号
{
    Const_e,  //欧拉常数e
    Const_pi, //圆周率π
    //可以此处添加新的数学常量序号
};
CONST struct  //常量结构
{
    PTSTR ptzConstName;
    CONST DOUBLE fData;
}
c_sConstant[] = //常量名称和常量数值列表
{
    {TEXT("e"),  2.71828182845904523536}, //欧拉常数e
    {TEXT("pi"), 3.14159265358979323846}, //圆周率π
    //可在此添加新的数学常量名称和数值
};
///////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////
CONST enum cFuncIndex //函数序号
{
    Func_abs,    //绝对值函数
    Func_arccos, //反余弦函数
    Func_arcctg, //反余切函数
    Func_arcsin, //反正弦函数
    Func_arctan, //反正切函数
    Func_ceil,   //向上取整
    Func_cos,    //余弦函数
    Func_ctg,    //余切函数
    Func_deg,    //弧度转角度
    Func_exp,    //e的幂函数
    Func_floor,  //向下取整
    Func_hypot,  //直角三角形弦长
    Func_lg,     //10的对数
    Func_ln,     //自然对数
    Func_log,    //对数函数
    Func_mod,    //余数函数
    Func_pow,    //幂函数
    Func_pow10,  //10幂函数
    Func_rad,    //角度转弧度
    Func_rand,   //随机函数
    Func_sin,    //正弦函数
    Func_sqrt,   //开方函数
    Func_tan,    //正切函数
   //可在此添加新的数学函数序号
};
CONST TCHAR c_sFuncName[][16] = //函数名列表
{
    TEXT("abs"),    //绝对值函数
    TEXT("arccos"), //反余弦函数
    TEXT("arcctg"), //反余切函数
    TEXT("arcsin"), //反正弦函数
    TEXT("arctan"), //反正切函数
    TEXT("ceil"),   //向上取整
    TEXT("cos"),    //余弦函数
    TEXT("ctg"),    //余切函数
    TEXT("deg"),    //弧度转角度
    TEXT("exp"),    //e的幂函数
    TEXT("floor"),  //向下取整
    TEXT("hypot"),  //直角三角形弦长
    TEXT("lg"),     //10的对数
    TEXT("ln"),     //自然对数
    TEXT("log"),    //对数函数
    TEXT("mod"),    //取余数函数
    TEXT("pow"),    //幂函数
    TEXT("pow10"),  //10的幂函数
    TEXT("rad"),    //角度转弧度
    TEXT("rand"),   //随机函数
    TEXT("sin"),    //正弦函数
    TEXT("sqrt"),   //开方函数
    TEXT("tan"),    //正切函数
    //可在此添加新的数学函数
    //添加新的数学函数后,再在下在的函数 CalcFunctionExpression 中添加它的功能
};

功能如下:
数学表达式计算命令,By Lxl1638
使用方法:  Calculator.EXE {代数表达式}#小数位数(默认6位最多16位)
支持的运算符号: 加"+"、减"-"、乘"*"、除"/"、幂"^"和括号解释
支持的数学常数: e    表示欧拉常数, pi    表示圆周率π
支持的数学函数: 共计23个
    abs(a) 绝对值函数
    arccos(a) 反余弦函数
    arcctg(a) 反余切函数
    arcsin(a) 反正弦函数
    arctan(a) 反正切函数
    ceil(a) 向上取整
    cos(a) 余弦函数
    ctg(a) 余切函数
    deg(a) 弧度转角度
    exp(a) e的幂函数
    floor(a) 向下取整
    hypot(a,b) 直角三角形弦长
    lg(a) 10的对数
    ln(a) 自然对数
    log(a.b) 对数函数
    mod(a,b) 余数函数
    pow(a,b) 幂函数
    pow10(a) 10幂函数
    rad(a) 角度转弧度
    rand(a) 随机函数
    sin(a) 正弦函数
    sqrt(a) 开方函数
    tan(a) 正切函数

使用示例: Calculator.EXE 2*arcsin(sin(pi/2))#8

示例演示(红色这样的表达式够复杂了):
J:\>Calculator.exe exp[(56-(((((((sin[(1+29)*pi/180]+3+2.5)+4)+sin[30*pi/180]+4.5)+6)+7)+8)+9)-10)]+56-sin[30*pi/180]+4.5
62.7183






[ 本帖最后由 lxl1638 于 2010-11-22 10:54 编辑 ]

Calculator_最终版.rar

4.33 KB, 下载次数: 275, 下载积分: 无忧币 -2

Calculator_源码.rar

76.38 KB, 下载次数: 254, 下载积分: 无忧币 -2

2#
发表于 2010-11-11 23:12:33 | 只看该作者
好工具,下载收藏先!
回复

使用道具 举报

3#
发表于 2010-11-12 00:30:24 | 只看该作者
不得不顶,老大就是强!!
回复

使用道具 举报

4#
发表于 2010-11-12 00:43:15 | 只看该作者
下载备用。感谢分享。
回复

使用道具 举报

5#
发表于 2010-11-12 01:24:41 | 只看该作者
是否支持十六进制数的计算,十进制十六进制的相互转换?
一直想找一个好点的计算器,找不到,数据恢复中用到没有好用的。
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=57675&page=260#pid2062761
回复

使用道具 举报

6#
 楼主| 发表于 2010-11-12 09:31:04 | 只看该作者
原帖由 freesoft00 于 2010-11-12 01:24 发表
是否支持十六进制数的计算,十进制十六进制的相互转换?
一直想找一个好点的计算器,找不到,数据恢复中用到没有好用的。
http://bbs.wuyou.net/forum.php?mod=viewthread&tid=57675&page=260#pid2062761


你给那个 Excel  宏本人不是很明白,具你要什么样的功能,说明一下。
回复

使用道具 举报

7#
发表于 2010-11-12 09:39:01 | 只看该作者
九大又发精品啦,收下,谢谢。
回复

使用道具 举报

8#
发表于 2010-11-12 11:47:25 | 只看该作者
一些涉及到的计算:

扇区=簇×簇大小

字节数=扇区数×512(非512字节的乘以实际数)

分区大小=字节数÷2的30次方 (单位G)

分区大小=扇区总数×512÷1204÷1024÷1024

根目录的地址=保留扇区+FAT表数量*每FAT扇区数

单个FAT表大小=(((分区大小÷每扇区字节数-保留扇区)÷簇大小-2)×4÷每扇区字节数)-((分区大小÷每扇区字节数)%簇大小)

某簇的起始扇区号=保留扇区数+每个fat表大小扇区数×fat表个数+(该簇簇号-2×每簇扇区数)

1.FAT表大小=根目录的位置—FAT2的位置

2. FAT1表的起始位置=FAT2的位置-FAT表的大小

3.簇大小,FAT32一般根目录的起始位置为第二簇,向下搜索2E202020H,查看其关于自身位置的描述,如果为3,那么簇大小就等于2E202020H的扇区号 减去 根目录所在的扇区号 = 簇大小(扇区)。


FAT簇大小计算:

方法一:
FAT32是4位,
(分区总扇区数 - 保留扇区数 - 文件分配表扇区数 X 2) / (文件分配表扇区数 X 512 / 4),
结果向下取整即为每簇扇区数。

FAT16是2位
FAT12是1.5位
(分区总扇区数 - 保留扇区数 - 文件分配表扇区数 X 2) / (文件分配表扇区数 X 512 / 1.5)
结果向下取整即为每簇扇区数。

方法二:
关键字:2E202020 找出子目录的所在扇区数及目录项中描述的位置(是以簇来表示的,注意:这子目录不能是已经删除的,因为在FAT中,删除后高位会被清零)
例如:
      子目录所在扇区数                       目录项中描述的位置
            3136                                     608         
            3198                                     639           
所以   簇大小=(3198-3136)/(639-608)=2  




关于FAT分区文件系统各相关要素的计算分配

一、FAT分区的内容组成:

FAT文件系统将分区分为如下几个部分:

1.DBR;2.FAT;(3.FDT;)4.DATA;5.Idel Space。当一个分区大小确定以后,这几个区域的位置也就大致确定了下来。

二、几个区域的相互位置及大小:

1.DBR:总是从分区的第一个扇区开始,其大小为32-38 sectors(FAT16为2扇区);它的大小也就是DBR的BPB参数表中偏移0e处的隐含扇区数。

2.剩余扇区(Idel Space):分区后边不能利用的扇区,通常与分区内簇的大小有关。

设:DATA为自数据区开始,至分区结束的扇区数。数据区的有效扇区数为S(d),分区剩余扇区数为S(i),分区簇的大小为m

DATA = S(d) + S(i)…………(1)

S(i) = DATA mod m …………(2)

其中,mod为模取运算符。

3.FAT:由两个大小相同的部分组成,其中后一个为前一个的备份。其具体大小是可变。其位置总是位于DBR之后。

4.FDT(DATA):在FAT16中,FDT大小为固定的32扇区。在FAT32中,FDT已经成为的数据区(DATA)的一部分,位于DATA的最前边,其大小已不限于32扇区。FDT(DATA)的起始位

置(相对于FAT32,就是DATA的开始)相对是不太固定的。

三、FAT分区的DATA的大小及起始位置计算方法:

设:分区扇区总数为S总,则有下式成立:

S总= DBR + 2*FAT + DATA …………(3)

2*FAT + DATA = S总 - DBR …………(4)

因为 数据区总簇数= {DATA / m},则每个FAT所占扇区数为:

FAT={DATA/m/a}  …………(5)

这里{ }表示向上取整运算;a为每FAT扇区能表示和簇数,相对于FAT16/32,a分别取值256、128。

将式(5)代入式(4),于是有:

2*{DATA/m/a}  + DATA = S总 -  DBR…………(6)

对于任何一个分区来说,如果分区大小及簇大小一经确定,式(6)的右边就成为了一个常量,所剩下的惟一一个未知因数DATA也就得以确定。

分区剩余扇区数S(i)由式(2 )确定,而FAT所占用的扇区数是由式(5)确定的。

[ 本帖最后由 freesoft00 于 2010-11-12 11:54 编辑 ]
回复

使用道具 举报

9#
发表于 2010-11-12 11:49:28 | 只看该作者
涉及到的计算并不是太复杂,希望计算过程有一个日志,能下是每一步,这样可以复查计算是否有误。
命令行程序或者带界面的程序都可以。

windows自带的也可以计算,但是没有日志框显示每一步,计算一个说不定用到上面的数忘记了,还得手工计上。不能输入计算公式,只能一个一个的算。

[ 本帖最后由 freesoft00 于 2010-11-12 11:54 编辑 ]
回复

使用道具 举报

10#
 楼主| 发表于 2010-11-12 12:29:20 | 只看该作者
原帖由 freesoft00 于 2010-11-12 11:47 发表
一些涉及到的计算:

扇区=簇×簇大小

字节数=扇区数×512(非512字节的乘以实际数)

分区大小=字节数÷2的30次方 (单位G)

分区大小=扇区总数×512÷1204÷1024÷1024

根目录的地址=保留扇区+F ...


看得很头晕!要支持这样的功能就相当于要有执行脚本的功能了,本人目前难以完成。
现在的打算是准备将这个工具的功能集成到 PECMD 的 CALC 命令中,或者那个时候
可以实现你的要求,因为 PECMD 可以通过 ENVI 命令记录每一步的计算结果。

现在相了解的是,你这个计算过程中有没有出现很小的小数,如小于 0.0001 下的小数。
回复

使用道具 举报

11#
发表于 2010-11-12 12:39:16 | 只看该作者
我对这方面也不太了解,也是刚刚接触了。我猜测可能没有 0.0001 下的小数吧。
具体的lvyanan 也许清楚,他研究数据恢复。
回复

使用道具 举报

12#
发表于 2010-11-12 13:02:14 | 只看该作者
问了一下lvyanan ,他说没有很小的小数,如小于 0.0001 下的小数
回复

使用道具 举报

13#
发表于 2010-11-12 21:01:05 | 只看该作者
不错,感谢分享。。。。
回复

使用道具 举报

14#
发表于 2010-11-14 00:04:54 | 只看该作者
原帖由 lxl1638 于 2010-11-11 23:06 发表
计算功能比 wtcmd 强多了。

理论上支持无穷表达式计算,支持错误表达式说明。

功能如下:

数学表达式计算命令,By Lxl1638
使用方法:  
Calculator.EXE  {代数表达式} #小数位数(默认4位最多6位)
...


老大不是专门冲着我来的吧,但愿不是,那样不太好。疑问:小数为什么要限制为6位呢?double可以有15个有效数字,不能表示出的数可以用<climits>中的DBL_EPSILON或<limits>中的numeric_limits<double>::epsilon()表示的啊。

[ 本帖最后由 shoulea 于 2010-11-14 00:06 编辑 ]
回复

使用道具 举报

15#
发表于 2010-11-14 00:05:46 | 只看该作者
原帖由 freesoft00 于 2010-11-12 11:49 发表
涉及到的计算并不是太复杂,希望计算过程有一个日志,能下是每一步,这样可以复查计算是否有误。
命令行程序或者带界面的程序都可以。

windows自带的也可以计算,但是没有日志框显示每一步,计算一个说不定 ...


这个建议不错,应该实现。
回复

使用道具 举报

16#
 楼主| 发表于 2010-11-14 00:35:24 | 只看该作者
原帖由 shoulea 于 2010-11-14 00:04 发表


老大不是专门冲着我来的吧,但愿不是,那样不太好。疑问:小数为什么要限制为6位呢?double可以有15个有效数字,不能表示出的数可以用中的DBL_EPSILON或中的numeric_limits::epsilon()表示的啊。

不会,这仅仅是测试,这个工具不会加入执行脚本功能,
实际上就现行的代码加入执行脚本功能是很容易的事了:
1、加入一条 Load 命令载入脚本,按流程执行;
2、构建变量系统,内置若干个变量,如 double m_X[16]; INT64 m_I[16];
3、遇到如 X0 = {表达式} 这样的命令就将结果保存到 m_X[0] 中;
4、表达式中出现 X0 这样的字符就引用变量 m_X[0]。

但这个工具的功能会集成到 PECMD 中,相信不会与你的工具冲突。

另,double类型数值可以达到16位小数(15位有效,第16位是估计值),
作为测试,这个工具只是想测试设置小数位数的输出功能是否正常而已。

[ 本帖最后由 lxl1638 于 2010-11-14 00:41 编辑 ]
回复

使用道具 举报

17#
发表于 2010-11-14 10:50:25 | 只看该作者
原帖由 lxl1638 于 2010-11-14 00:35 发表

不会,这仅仅是测试,这个工具不会加入执行脚本功能,
实际上就现行的代码加入执行脚本功能是很容易的事了:
1、加入一条 Load 命令载入脚本,按流程执行;
2、构建变量系统,内置若干个变量,如 double m ...


将三角函数等等强大功能加到pecmd里去就没必要,毕竟谁会用pecmd/wtcmd做数学计算,实际wtcmd最后把calcexpr中的许多功能都砍掉了,只保留了+ - * / div mod [取整] (括号)几种简单功能,所以不妨将一些简单实用的功能集成到pecmd中,而其余部分独立出来,做成比Unix bc/dc更强大的工具。

对了,你所说的那些特性《C++程序设计语言:特别版》就有一个例子,用一个map做,很好弄的。

[ 本帖最后由 shoulea 于 2010-11-14 10:53 编辑 ]
回复

使用道具 举报

18#
 楼主| 发表于 2010-11-14 10:59:00 | 只看该作者
原帖由 shoulea 于 2010-11-14 10:50 发表


将三角函数等等强大功能加到pecmd里去就没必要,毕竟谁会用pecmd/wtcmd做数学计算,实际wtcmd最后把calcexpr中的许多功能都砍掉了,只保留了+ - * / div mod [取整] (括号)几种简单功能,所以不妨将一些简单 ...


反正加上去 EXE 体积几乎不增大,加了也好。
回复

使用道具 举报

19#
发表于 2010-11-15 02:01:31 | 只看该作者
下面是网摘:

同诸多网友一样,受益于VCKBASE,觉得应为他做点贡献了,于是做了这么一个基于表达式求值的科学计算器与各位爱好编程的朋友分享。
  如您所知,这方面的程序很多,看过ZF.Yi的相关作品,也见过黄江峰的相关程序,但我觉得我的计算类有不同于二位的特色,如计算结果的有效位较长(16位);支持不严格的表达式输入(如cos(23)*sin(34)与cos(23)*sin(34与cos23*sin34等价);支持四种进制的数在一个表达式中同时出现的进制混合运算(除十进制外的各进制数不限于整数,如12d.3axh,xh是我的计算类所能识别的十六进制数的标识符);且程序做得也比较精细(如制作了鼠标键盘、窗口跟随、计算历史查看等),这才使我觉得拙作不致于滥竽充数,相信网友们看了会另有收获的。

代码更新说明:
有的网友发邮件给我指出了其中的不足之处,如没有处理好连加连减或加减号混合出现的情况(如:1++++1,1----1,--+-+-+1-+-++++---1)。我也发现了这个问题,所以重写了其中的MultiE(CString *strExp)计算函数。同时应一些网友的议建,加入了对结果的十六、八、二进制转换(以前只能在计算过程中转换)


源代码如下:
Calculator.rar (28.44 KB, 下载次数: 31)

我不懂程序,老九看看有用没有,里面有错误没有,能帮编译一个最好,谢谢!
回复

使用道具 举报

20#
发表于 2010-11-15 10:02:48 | 只看该作者
老九干脆做个计算器的gui算了!
回复

使用道具 举报

21#
 楼主| 发表于 2010-11-15 11:05:58 | 只看该作者
原帖由 freesoft00 于 2010-11-15 02:01 发表
下面是网摘:



源代码如下:
104881

我不懂程序,老九看看有用没有,里面有错误没有,能帮编译一个最好,谢谢!


VC6的源码,本人试了一下,在VC2005中不能直接编译,没有认真去看,看别人的源码是一件很头晕的事。
简单看了一下源码和说明,支持的函数不多,关键是修改扩展困难。

如果有兴趣,可以到一楼下载本人的源码,本人这个源码要扩展功能,如舔加新的数学常量和新的数学函数相当容易,
在源码的头文件( CALC.H )开始处说明如何舔加新的数学常量和新的数学函数,相当容易。

[ 本帖最后由 lxl1638 于 2010-11-15 11:28 编辑 ]
回复

使用道具 举报

22#
发表于 2010-11-15 12:41:01 | 只看该作者
首先谢谢老九!难者不会会者不难,关键我不会编程。

转发上面那个主要看他的介绍不错,能满足我的使用需求:


支持四种进制的数在一个表达式中同时出现的进制混合运算(除十进制外的各进制数不限于整数,如12d.3axh,xh是我的计算类所能识别的十六进制数的标识符、支持计算历史查看等,加入了对结果的十六、八、二进制转换(以前只能在计算过程中转换)
回复

使用道具 举报

23#
发表于 2010-11-15 13:06:06 | 只看该作者
先感谢偶像分享的源码!
回头再细看……
回复

使用道具 举报

24#
 楼主| 发表于 2010-11-15 13:35:02 | 只看该作者
原帖由 freesoft00 于 2010-11-15 12:41 发表
首先谢谢老九!难者不会会者不难,关键我不会编程。

转发上面那个主要看他的介绍不错,能满足我的使用需求:

本人这个最终版已支持16进制数值了,只是输出结果没有支持16进制。

BOOL TStrIsHexadecimal(PCTSTR ptzExpression)//判断一个字符串表达式是否属16进制数据

[ 本帖最后由 lxl1638 于 2010-11-15 13:39 编辑 ]
回复

使用道具 举报

25#
发表于 2010-11-15 14:23:15 | 只看该作者
谢谢了!复杂点的运算还是表达式好,全部输入完一下就出来了。如果是windows自带的计算器还得一个一个的算,一个一个的记。计算器一开始是计算的,现在找个好点的计算器真难,我在xdowns和greendown下载站还有其它的下载站几乎下载试用了所有的计算器都不是太好用,要么不支持表达式,要么不支持十六进制,要么广告太多,要么被杀毒软件报毒。唉。。。

如果输出结果可以支持16进制就好了。哈哈。
回复

使用道具 举报

26#
发表于 2010-11-15 15:19:03 | 只看该作者
好东西阿,好东西阿…………
回复

使用道具 举报

27#
发表于 2010-11-15 15:37:07 | 只看该作者
看来是我不太会用呀,微软的那个汉化版的PowerCalc就挺好用,支持表达式,支持二进制、十进制、十六进制输出。支持自定义变量和函数,但是我不知道如何自己增加变量,不知道格式点击增加不起作用。
以前试的时候十六进制我是ff+aa提示错误,原来要在前面加0x才可以。
回复

使用道具 举报

28#
发表于 2010-11-15 22:17:12 | 只看该作者
楼主用什么软件做的,弄个c语言的吧+源码。谢啦
回复

使用道具 举报

29#
发表于 2010-11-16 04:29:37 | 只看该作者
支持!如果不十分追求程序大小的话,建议用Boost.Spirit来作语法分析,可以轻松的实现更复杂更强大的功能,而且编码量也小,算个四则表达式估计也就50行左右的代码量。
回复

使用道具 举报

30#
 楼主| 发表于 2010-11-16 11:14:41 | 只看该作者
原帖由 StarsunYzL 于 2010-11-16 04:29 发表
支持!如果不十分追求程序大小的话,建议用Boost.Spirit来作语法分析,可以轻松的实现更复杂更强大的功能,而且编码量也小,算个四则表达式估计也就50行左右的代码量。


不懂什么Boost.Spirit,但本人这个源码已完善了,只要在说明的相应位置补充要添加的数学常量或数学函数就可以扩展功能,
无需考虑代码如何去解释这些数学常量和数学函数,因为代码已完成了这样的解释功能 --- 这是源码最亮丽的地方。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2025-2-26 17:52

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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