相信很多人,在工作中会需要使用到计算器。一般的做法是,打开并使用系统自带的计算器。

这种做法可能对我来说,有如下几个问题。

  • 太慢。每次需要打开计算器,然后改成编程模式,手工选择进制,再使用输入表达式进行计算。

  • 需要切换窗口。编程时经常是在终端中,使用GUI计算器则意味着要离开终端,计算完毕再切换回来。

  • 无法使用混合进制表达式。混合进制的意思是,在一个表达式中同时使用多种进制,如“0x10 * 10”表示十六进制的0x10乘以十进制的10。

如果以上有一条你也有同感的话,那么你也应该试一下,使用命令行计算器。

命令行计算器,调用bc

只需经过简单的搜索,便可以了解到,linux中原生提供了一个命令行计算器 GNU bc。

GNU bc支持高精度数字和多种数值类型(例如二进制、十进制、十六进制)的输入输出。

bc的交互式使用方式,运行bc,进入交互模式。在交互模式中输入表达式,回车即可获得结果。需要退出时输入quit退出即可。

bc的非交互式使用方式,通过管道将表达式传入。

使用效果如下

  1. zhuangqiubin@zhuangqiubin-PC:~$ bc
  2. bc 1.07.1
  3. Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006, 2008, 2012-2017 Free Software Foundation, Inc.
  4. This is free software with ABSOLUTELY NO WARRANTY.
  5. For details type `warranty'.
  6. 1+2
  7. 3
  8. quit
  9. zhuangqiubin@zhuangqiubin-PC:~$ echo "1+2" | bc
  10. 3

OK,get到了命令行计算器的新技能了,但每次进入交互模式或者手工输入“echo 表达式 | bc ”都感觉略麻烦。那这个时候,就需要脚本,写个mycalc.sh好了

  1. zhuangqiubin@zhuangqiubin-PC:~$ cat mycalc.sh
  2. #!/bin/bash
  3. echo "$@" | bc
  4. zhuangqiubin@zhuangqiubin-PC:~$ ./mycalc.sh 1+2
  5. 3

再把mycalc.sh拷贝到可访问的目录下,如

  1. sudo mv mycalc.sh /usr/bin

对于没有sudo权限的情况,那也可以变通下

  1. mkdir -p ~/usr/bin
  2. mv mycalc.sh ~/usr/bin
  3. echo 'export PATH=$HOME/usr/bin:$PATH' >> ~/.bashrc
  4. source ~/.bashrc

再alias一个顺手的命令名,比如拼音jisuan

  1. echo "alias jisuan='mycalc.sh'" >> ~/.bashrc

更多bc的用法,可以通过man bc查看,网上也有许多介绍资料。

解决进制问题

bc仍然需要手工指定进制,在表达式前,使用ibase参数和obase参数指定输入输出的进制。并且不支持混合进制,因为ibase每次只能指定一种进制。

  1. zhuangqiubin@zhuangqiubin-PC:~$ echo "10+10" | bc
  2. 20
  3. zhuangqiubin@zhuangqiubin-PC:~$ echo "ibase=16;10+10" | bc
  4. 32

但我们既然已经有了一个包装脚本mycalc.sh,那是不是可以把进制转换的工作交给它呢,当然可以。

我们可以让mycalc.sh先处理下表达式中的数字,约定0x开头为十六进制,不带前缀为十进制,0o开头为八进制,0b开头为二进制。

mycalc先将所有参数转换成统一的进制,如十进制,然后计算表达式的值,最终将结果再以多种进制的形式输出。这样我们就不同手工处理进制问题了。

至于输出,为了方便起见,可以多种进制一起输出,需要哪个用哪个即可

这里就不贴代码了,有兴趣可移步github https://github.com/zqb-all/smartbc,我们接着往下看,后面有更简单的方式。

使用示例

  1. zhuangqiubin@zhuangqiubin-PC:~$ type jisuan
  2. jisuan `~/mywork/mygithub/smartbc/smartbc' 的别名
  3. zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+10
  4. Original EQUATION: 10+10
  5. Decimal EQUATION: 10+10
  6. base2 : 10100
  7. base8 : 24
  8. base10: 20
  9. base16: 14
  10. zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
  11. Original EQUATION: 10+0x10
  12. Decimal EQUATION: 10+16
  13. base2 : 11010
  14. base8 : 32
  15. base10: 26
  16. base16: 1A

更好的实现,使用python

以上基于bc的计算器,已经可以满足我的需求了,也使用了一段时间。但其实还有更好的实现方式,使用python。

在命令行中,输入python,进入交互模式,即可像bc一样执行表达式,得到结果。更棒的是,原生支持混合进制,不需要自己写代码预处理表达式了。简单可靠。

代码及使用示例

  1. zhuangqiubin@zhuangqiubin-PC:~$ type jisuan
  2. jisuan `~/.pycalc.py' 的别名
  3. zhuangqiubin@zhuangqiubin-PC:~$ cat ~/.pycalc.py
  4. #!/usr/bin/env python2
  5. import sys
  6. equation=sys.argv[1]
  7. result=eval(equation)
  8. if isinstance(result, (float)):
  9. print "Attention:only base10 is float, others change to int before type"
  10. print "equation:",sys.argv[1]
  11. print "base2 : ",str(bin(int(result)))
  12. print "base8 : ",str(oct(int(result)))
  13. print "base10: ",str((result))
  14. print "base16: ",str(hex(int(result)))
  15. zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+10
  16. equation: 10+10
  17. base2 : 0b10100
  18. base8 : 024
  19. base10: 20
  20. base16: 0x14
  21. zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
  22. equation: 10+0x10
  23. base2 : 0b11010
  24. base8 : 032
  25. base10: 26
  26. base16: 0x1a

更多输出格式

一般,输出十六进制,十进制,二进制三种结果就足够用了。但如果有特殊需求,也可自己拓展。

比如,当需要核对寄存器,检查某个bit时,一个个去数二进制的第19位,是很费眼睛的一件事。

这个时候就需要更加直观的输出,可以一眼看到某个bit是0还是1。

那好办,给二进制加上下标好了。如下

代码

  1. #!/usr/bin/env python2
  2. import sys
  3. def formatBinString(num):
  4. result='bit: '
  5. result_index='index: '
  6. num_len=len(num)
  7. if num_len > 32:
  8. return ""
  9. for i in num:
  10. num_len-=1
  11. result+=i
  12. result+=' | '
  13. result_index+=str(num_len).zfill(2)
  14. result_index+='| '
  15. return result+'\n'+result_index
  16. equation=sys.argv[1]
  17. result=eval(equation)
  18. if isinstance(result, (float)):
  19. print "Attention:only base10 is float, others change to int before type"
  20. print "equation:",sys.argv[1]
  21. print ""
  22. print "base2 : ",str(bin(int(result)))
  23. print "base8 : ",str(oct(int(result)))
  24. print "base10: ",str((result))
  25. print "base16: ",str(hex(int(result)))
  26. print ""
  27. print formatBinString(str(bin(int(result))[2:].zfill(32)))

效果

  1. zhuangqiubin@zhuangqiubin-PC:~$ jisuan 10+0x10
  2. equation: 10+0x10
  3. base2 : 0b11010
  4. base8 : 032
  5. base10: 26
  6. base16: 0x1a
  7. 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 |
  8. 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命令行计算器的更多相关文章

  1. linux命令行计算器 <转>

    转自 http://blog.chinaunix.net/uid-26959241-id-3207711.html 详细文档请 man bc 在windows下,大家都知道直接运行calc,(c:\w ...

  2. 【转载】linux命令行计算器bc的一个“坑”

    [转载自]http://blog.chinaunix.net/uid-174325-id-3518953.html 结论:ibase,obase可以使用在不同的计算公式里,但是尽量把obase放iba ...

  3. 像黑客一样使用 Linux 命令行

    前言 之前在博客园看到一篇介绍 IntelliJ IDEA 配置的文章,它里面用的是 gif 动态图片进行展示,我觉得很不错.所以在我今天以及以后的博文中,我也会尽量使用 gif 动图进行展示.制作 ...

  4. 详解Linux命令行下常用svn命令

    1.Linux命令行下将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.1/pro/do ...

  5. linux 命令行 光标移动技巧

    linux 命令行 光标移动技巧 看一个真正的专家操作命令行绝对是一种很好的体验-光标在单词之间来回穿梭,命令行不同的滚动.在这里强烈建立适应GUI节目的开发者尝试一下在提示符下面工作.但是事情也不是 ...

  6. 在linux命令行下执行php 程序

    如何在linux命令行下,执行php程序. 例子 打印当前时间 php -r "echo time()" 随机输出一个数字 php -r "echo rand(1,20) ...

  7. git代理,windows命令行代理,linux命令行代理

    下载不动设置代理:git config --global http.proxy http://127.0.0.1:1080git config --global https.proxy https:/ ...

  8. [转]12款最佳Linux命令行终端工具

    摘要 “工欲善其事必先利其器”,作为菜鸟,也是从别人那里偷学来的一些东东.今天看到同事用到一个终端命令行工具,觉得自己弱爆了.然后在网上搜了下该工具.发现类似的工具还是挺多的,只是自己不知道罢了. 原 ...

  9. Linux命令行修改IP、网关、DNS、主机名 的方法

    修改主机名:[改里面的 HOSTNAME 即可] vim /etc/sysconfig/network 网卡eth0    IP修改为 102.168.0.1 ifconfig eth0 102.16 ...

随机推荐

  1. Python 并发编程:PoolExecutor 篇

    个人笔记,如有疏漏,还请指正. 使用多线程(threading)和多进程(multiprocessing)完成常规的并发需求,在启动的时候 start.join 等步骤不能省,复杂的需要还要用 1-2 ...

  2. python进阶训练

    1.列表,字典,集合解析 from random import randint #列表解析,选出大于0的元素 data=[randint(-10,10)for i in range(10)] resu ...

  3. 常用的gif加载动态图片

    精心搜集的网页素材,包括:Loading GIF动画,"正在加载中"小图片,"请等待"小图标等,欢迎您的下载. 提示:点击鼠标右键,选择”图片另存为“即可轻松保 ...

  4. python基础之删除文件及删除目录的方法

    下面来看一下python里面是如何删除一个文件及文件夹的~~ 1 2 3 4 5 6 7 8 #首先引入OS模块 import os #删除文件:  os.remove() #删除空目录:  os.r ...

  5. WebStorm强大的调试JavaScript功能(转载)

    一.JavaScript的调试 目前火狐和Chrome都具备调试JavaScript的功能,而且还是相当的强大.如果纯粹是用浏览器来进行js调试的话,我比较喜欢用火狐.火狐可以安装各种插件,真的是非常 ...

  6. gdb调试行号错位

    http://blog.csdn.net/wangxmin2005/article/details/8128192 gdb调试过程中出现行号错位的情况,原因一般有两个: 1. 编译器的优化可能把某些语 ...

  7. JMS实战——ActiveMQ实现Pub-Sub

    前言 上篇博客<JMS实战--ActiveMQ>介绍了ActiveMQ的安装,并实现了简单的PTP模型.这篇博客我们来看一下Pub-Sub模型,之后来总结一下JMS. 实现 项目结构 其中 ...

  8. Netscaler的超高端口复用助力应对公网地址紧张

    Netscaler的超高端口复用助力应对公网地址紧张 http://blog.51cto.com/caojin/1898351 经常会有人问一个IP只有65535(姑且不考虑预留端口),从Big-ip ...

  9. [洛谷P1120]小木棍 [数据加强版]

    题目大意:有一些同样长的木棍,被切割成几段(长$\leqslant$50).给出每段小木棍的长度,找出原始木棍的最小可能长度. 题解:dfs C++ Code: #include<cstdio& ...

  10. 算法学习——kruskal重构树

    kruskal重构树是一个比较冷门的数据结构. 其实可以看做一种最小生成树的表现形式. 在普通的kruskal中,如果一条边连接了在2个不同集合中的点的话,我们将合并这2个点所在集合. 而在krusk ...