相信很多人, 在工作中会需要使用到计算器. 一般的做法是, 打开并使用系统自带的计算器.
这种做法可能对我来说, 有如下几个问题.
太慢. 每次需要打开计算器, 然后改成编程模式, 手工选择进制, 再使用输入表达式进行计算.
需要切换窗口. 编程时经常是在终端中, 使用 GUI 计算器则意味着要离开终端, 计算完毕再切换回来.
无法使用混合进制表达式. 混合进制的意思是, 在一个表达式中同时使用多种进制, 如 "0x10 * 10" 表示十六进制的 0x10 乘以十进制的 10.
如果以上有一条你也有同感的话, 那么你也应该试一下, 使用命令行计算器.
只需经过简单的搜索, 便可以了解到, 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|
来源: https://www.cnblogs.com/zqb-all/p/9763219.html