一步步打造自己的linux命令行计算器
相信很多人,在工作中会需要使用到计算器。一般的做法是,打开并使用系统自带的计算器。
这种做法可能对我来说,有如下几个问题。
太慢。每次需要打开计算器,然后改成编程模式,手工选择进制,再使用输入表达式进行计算。
需要切换窗口。编程时经常是在终端中,使用GUI计算器则意味着要离开终端,计算完毕再切换回来。
无法使用混合进制表达式。混合进制的意思是,在一个表达式中同时使用多种进制,如“0x10 * 10”表示十六进制的0x10乘以十进制的10。
如果以上有一条你也有同感的话,那么你也应该试一下,使用命令行计算器。
命令行计算器,调用bc
只需经过简单的搜索,便可以了解到,linux中原生提供了一个命令行计算器 GNU bc。
GNU bc支持高精度数字和多种数值类型(例如二进制、十进制、十六进制)的输入输出。
bc的交互式使用方式,运行bc,进入交互模式。在交互模式中输入表达式,回车即可获得结果。需要退出时输入quit退出即可。
bc的非交互式使用方式,通过管道将表达式传入。
使用效果如下
zhuangqiubin@zhuangqiubin-PC:~$ bc
bc 1.07.1
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+2
3
quit
zhuangqiubin@zhuangqiubin-PC:~$ echo "1+2" | bc
3
OK,get到了命令行计算器的新技能了,但每次进入交互模式或者手工输入“echo 表达式 | bc ”都感觉略麻烦。那这个时候,就需要脚本,写个mycalc.sh好了
zhuangqiubin@zhuangqiubin-PC:~$ cat mycalc.sh
#!/bin/bash
echo "$@" | bc
zhuangqiubin@zhuangqiubin-PC:~$ ./mycalc.sh 1+2
3
再把mycalc.sh拷贝到可访问的目录下,如
sudo mv mycalc.sh /usr/bin
对于没有sudo权限的情况,那也可以变通下
mkdir -p ~/usr/bin
mv mycalc.sh ~/usr/bin
echo 'export PATH=$HOME/usr/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
再alias一个顺手的命令名,比如拼音jisuan
echo "alias jisuan='mycalc.sh'" >> ~/.bashrc
更多bc的用法,可以通过man bc查看,网上也有许多介绍资料。
解决进制问题
bc仍然需要手工指定进制,在表达式前,使用ibase参数和obase参数指定输入输出的进制。并且不支持混合进制,因为ibase每次只能指定一种进制。
zhuangqiubin@zhuangqiubin-PC:~$ echo "10+10" | bc
20
zhuangqiubin@zhuangqiubin-PC:~$ echo "ibase=16;10+10" | bc
32
但我们既然已经有了一个包装脚本mycalc.sh,那是不是可以把进制转换的工作交给它呢,当然可以。
我们可以让mycalc.sh先处理下表达式中的数字,约定0x开头为十六进制,不带前缀为十进制,0o开头为八进制,0b开头为二进制。
mycalc先将所有参数转换成统一的进制,如十进制,然后计算表达式的值,最终将结果再以多种进制的形式输出。这样我们就不同手工处理进制问题了。
至于输出,为了方便起见,可以多种进制一起输出,需要哪个用哪个即可
这里就不贴代码了,有兴趣可移步github https://github.com/zqb-all/smartbc,我们接着往下看,后面有更简单的方式。
使用示例
zhuangqiubin@zhuangqiubin-PC:~$ type jisuan
jisuan 是 `~/mywork/mygithub/smartbc/smartbc' 的别名
zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+10
Original EQUATION: 10+10
Decimal EQUATION: 10+10
base2 : 10100
base8 : 24
base10: 20
base16: 14
zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
Original EQUATION: 10+0x10
Decimal EQUATION: 10+16
base2 : 11010
base8 : 32
base10: 26
base16: 1A
更好的实现,使用python
以上基于bc的计算器,已经可以满足我的需求了,也使用了一段时间。但其实还有更好的实现方式,使用python。
在命令行中,输入python,进入交互模式,即可像bc一样执行表达式,得到结果。更棒的是,原生支持混合进制,不需要自己写代码预处理表达式了。简单可靠。
代码及使用示例
zhuangqiubin@zhuangqiubin-PC:~$ type jisuan
jisuan 是 `~/.pycalc.py' 的别名
zhuangqiubin@zhuangqiubin-PC:~$ cat ~/.pycalc.py
#!/usr/bin/env python2
import sys
equation=sys.argv[1]
result=eval(equation)
if isinstance(result, (float)):
print "Attention:only base10 is float, others change to int before type"
print "equation:",sys.argv[1]
print "base2 : ",str(bin(int(result)))
print "base8 : ",str(oct(int(result)))
print "base10: ",str((result))
print "base16: ",str(hex(int(result)))
zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+10
equation: 10+10
base2 : 0b10100
base8 : 024
base10: 20
base16: 0x14
zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
equation: 10+0x10
base2 : 0b11010
base8 : 032
base10: 26
base16: 0x1a
更多输出格式
一般,输出十六进制,十进制,二进制三种结果就足够用了。但如果有特殊需求,也可自己拓展。
比如,当需要核对寄存器,检查某个bit时,一个个去数二进制的第19位,是很费眼睛的一件事。
这个时候就需要更加直观的输出,可以一眼看到某个bit是0还是1。
那好办,给二进制加上下标好了。如下
代码
#!/usr/bin/env python2
import sys
def formatBinString(num):
result='bit: '
result_index='index: '
num_len=len(num)
if num_len > 32:
return ""
for i in num:
num_len-=1
result+=i
result+=' | '
result_index+=str(num_len).zfill(2)
result_index+='| '
return result+'\n'+result_index
equation=sys.argv[1]
result=eval(equation)
if isinstance(result, (float)):
print "Attention:only base10 is float, others change to int before type"
print "equation:",sys.argv[1]
print ""
print "base2 : ",str(bin(int(result)))
print "base8 : ",str(oct(int(result)))
print "base10: ",str((result))
print "base16: ",str(hex(int(result)))
print ""
print formatBinString(str(bin(int(result))[2:].zfill(32)))
效果
zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
equation: 10+0x10
base2 : 0b11010
base8 : 032
base10: 26
base16: 0x1a
bit: 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 |
index: 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 09| 08| 07| 06| 05| 04| 03| 02| 01| 00|

一步步打造自己的linux命令行计算器的更多相关文章
- linux命令行计算器 <转>
转自 http://blog.chinaunix.net/uid-26959241-id-3207711.html 详细文档请 man bc 在windows下,大家都知道直接运行calc,(c:\w ...
- 【转载】linux命令行计算器bc的一个“坑”
[转载自]http://blog.chinaunix.net/uid-174325-id-3518953.html 结论:ibase,obase可以使用在不同的计算公式里,但是尽量把obase放iba ...
- 像黑客一样使用 Linux 命令行
前言 之前在博客园看到一篇介绍 IntelliJ IDEA 配置的文章,它里面用的是 gif 动态图片进行展示,我觉得很不错.所以在我今天以及以后的博文中,我也会尽量使用 gif 动图进行展示.制作 ...
- 详解Linux命令行下常用svn命令
1.Linux命令行下将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/do ...
- linux 命令行 光标移动技巧
linux 命令行 光标移动技巧 看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下面工作.但是事情也不是 ...
- 在linux命令行下执行php 程序
如何在linux命令行下,执行php程序. 例子 打印当前时间 php -r "echo time()" 随机输出一个数字 php -r "echo rand(1,20) ...
- git代理,windows命令行代理,linux命令行代理
下载不动设置代理:git config --global http.proxy http://127.0.0.1:1080git config --global https.proxy https:/ ...
- [转]12款最佳Linux命令行终端工具
摘要 “工欲善其事必先利其器”,作为菜鸟,也是从别人那里偷学来的一些东东.今天看到同事用到一个终端命令行工具,觉得自己弱爆了.然后在网上搜了下该工具.发现类似的工具还是挺多的,只是自己不知道罢了. 原 ...
- Linux命令行修改IP、网关、DNS、主机名 的方法
修改主机名:[改里面的 HOSTNAME 即可] vim /etc/sysconfig/network 网卡eth0 IP修改为 102.168.0.1 ifconfig eth0 102.16 ...
随机推荐
- C++学习013多态
何为多态 面向对象最要的特征之一就是多态,而纯虚函数是实现多态的主要方式.它可以提供一个通过用的接口,同样调用一个方法, 由于运算对象不同,方法也不同,这也就是所谓的动态绑定. #include &l ...
- NLP系列-中文分词(基于统计)
上文已经介绍了基于词典的中文分词,现在让我们来看一下基于统计的中文分词. 统计分词: 统计分词的主要思想是把每个词看做是由字组成的,如果相连的字在不同文本中出现的次数越多,就证明这段相连的字很有可能就 ...
- beta版本冲刺五
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:恺琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- OpenCV膨胀和腐蚀示例代码
#include<cv.h> #include<highgui.h> int main(int argc, char** argv) { IplImage* img = cvL ...
- [转] const int *a与int *const a,const int *const a的区别
http://blog.csdn.net/zhangheng837964767/article/details/33783511 关键问题点:const 属于修饰符 ,关键是看const 修饰的位置在 ...
- Linux杂技
挂载光盘 mkdir /mnt/cdrom #建立挂载点 mount /dev/cdrom /mnt/cdrom/ #挂载光盘 更换YUM源: cd /etc/yum.repos.d/ 使网络yum源 ...
- 从pthread 到QThread
该文出自:http://www.civilnet.cn/bbs/topicno/78430 使用线程技术进行应用编程的意义在gemfield的文章<从进程到线程>中已经介绍过了,我们就直奔 ...
- Maven中如何将源码之外的文件打包及添加本地jar
<build> <resources> <resource> <directory>src/main/resources</directory&g ...
- WebSocket简单介绍(WebSocket JavaScript 接口)(2)
上一节介绍了 WebSocket 规范,其中主要介绍了 WebSocket 的握手协议.握手协议通常是我们在构建 WebSocket 服务器端的实现和提供浏览器的WebSocket 支持时需要考虑的问 ...
- COGS 497——奶牛派对
奶牛派对 我们发现每头牛需要走的路程即为它到x的最短路+x到它的最短路. 转化: 于是这道题变成了一道典型的单源最短路问题,只需求出每个点到x的最短路dl,以及从x到此点的最短路d2,然后去找max( ...