linux脚本写的计算器,一步步打造自己的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先将所有参数转换成统一的进制,如十进制,然后计算表达式的值,最终将结果再以多种进制的形式输出。这样我们就不同手工处理进制问题了。

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

使用示例

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|

04c83179bc1a6c0eae99f074df2d68db.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode笔记】141. 环形链表(Java、快慢指针、链表)

文章目录题目描述思路 & 代码题目描述 常见题,用上了久违的快慢指针 思路 & 代码 举个例子就能明白了:我和汽车,进行一场比赛,跑道可能是环形跑道,也可能是直道。直道的话,将会以汽车撞到终点为…

【LeetCode笔记】169. 多数元素(Java、摩尔投票法、哈希表)

文章目录题目描述思路 & 代码思路一&#xff1a;哈希表思路二&#xff1a; 摩尔投票法题目描述 好家伙&#xff0c;这是今天最有意思的题目了 思路 & 代码 思路一&#xff1a;哈希表 先说缺点&#xff1a;空间复杂度O(n)一次遍历&#xff0c;记录<数组存储值&a…

【LeetCode笔记】206. 反转链表(Java、迭代、递归、链表)

啊好久没更文了&#xff0c;前两天状态不太好。还是要坚持更文敲题噢&#xff01; 文章目录题目描述思路 & 代码题目描述 面试高频题&#xff0c;需要会用两种方法解决&#xff01;&#xff08;迭代 and 递归&#xff09;其实先写出迭代&#xff0c;递归就不难写了。 思…

当你抛弃windows使用linux,当我们厌倦了Windows系统还能考虑什么样的桌面操作系统?...

如果你厌倦了Windows&#xff0c;我们该选择什么样的操作系统&#xff1f;时间告诉我们&#xff0c;任何事物都不会一成不变&#xff0c;当我们厌倦了Windows那天到来&#xff0c;不妨考虑换个操作系统&#xff0c;即便Windows操作系统在市场依然如日中天&#xff0c;旧的不去新…

【LeetCode笔记】234. 回文链表(Java、快慢指针、链表)

文章目录题目描述思路 & 算法题目描述 写这道题前最好把206.翻转链表 写了有空间复杂度的话都好说&#xff0c;不管是新建链表、还是用字符串equals都好做。 思路 & 算法 快慢指针&#xff1a; 快指针找终点&#xff0c;慢指针反转前半个链表快指针回到慢指针的位…

vs2010 编译linux,VS2010 Boost编译安装

2.解压缩到D:\boost 目录下3.编译bjam(1)从vs2010的工具菜单进入命令提示窗口(单击“开始”按钮&#xff0c;指向“所有程序”&#xff0c;指向“Microsoft Visual Studio 2010”&#xff0c;指向“Visual Studio tools(工具)”&#xff0c;然后单击“Visual Studio 2010 comma…

【LeetCode笔记】200. 岛屿数量(Java、DFS)

文章目录题目描述代码 & 思路更新代码题目描述 直接毁岛&#xff01;每次发现一个岛&#xff0c;ans&#xff0c;然后直接把整个岛毁了&#xff08;感染&#xff09;直到最后&#xff0c;找出所有岛&#xff0c;此时地图上全都是’0’ 代码 & 思路 每次找到一个岛&…

【LeetCode笔记】155. 最小栈(Java、栈)

文章目录题目描述思路 & 代码更新版题目描述 用空间换时间的经典例子&#xff0c;唯一要解决的地方就是 getMin() 如何实现常数检索&#xff08;貌似也是面试常考题&#xff09; 思路 & 代码 既然想快&#xff0c;那就要付出空间的代价用什么空间可以实现&#xff…

【LeetCode笔记】198. 打家劫舍(Java、动态规划)

文章目录题目描述思路 & 代码更新版题目描述 好家伙&#xff0c;真是一道不符合社会主义价值观的题目不过我们还是要把这道题做了&#xff0c;而且还得用上动态规划 思路 & 代码 首先&#xff0c;不能打劫相邻然后&#xff0c;房屋都是非负整数&#xff08;讲道理&…

【LeetCode笔记】617. 合并二叉树(Java、DFS、二叉树)

文章目录题目描述思路 & 代码更新版题目描述 貌似是面试高频题&#xff0c;显而易见的递归。 思路 & 代码 合并两棵树&#xff0c;先不考虑特殊情况&#xff0c;可以理解成&#xff1a;根结点合并&#xff0c;然后各自的左右子树继续进行合并操作。那么递归返回值肯…

【LeetCode笔记】226. 翻转二叉树(Java、递归)

文章目录题目描述代码 & 思路更新版题目描述 感觉和合并二叉树类似&#xff0c;都是很好进行递归的问题 代码 & 思路 翻转当前结点的左、右结点对当前结点的左、右结点进行翻转函数【自底向上】 /*** Definition for a binary tree node.* public class TreeNode …

virtualbox linux 分辨率,终于搞定了VirtualBox的ubuntu分辨率问题

曾经装了ubuntu&#xff0c;但是觉得和windows切换太麻烦了&#xff0c;要重启机器&#xff0c;导致的结果是linux装上了总是不用。这次决定使用虚拟机&#xff0c;因为我用ubuntu就是ssh一下实验室的服务器&#xff0c;所以对性能没什么要求。在所里的时候看到祝师兄总用vmwar…

【LeetCode笔记】160. 相交链表(Java、链表)

文章目录题目描述思路 & 代码题目描述 感谢这道题&#xff0c;让我更加了解到Dalao们思路的nb主要是满足空间复杂度O(1)。否则用哈希表不难实现。 思路 & 代码 有相交结点的情况下&#xff0c;可以找到这么一个等式&#xff1a; // 假设链表长度为m&#xff0c;n&…

【LeetCode笔记】152. 乘积最大子数组(Java、动态规划)

文章目录题目描述思路 & 代码更新版题目描述 考虑正数、负数和0的情况 思路 & 代码 既然是使用的动态规划&#xff0c;那么有以下几点&#xff1a; 维护什么&#xff1a;维护iMax和iMin&#xff0c;分别代表包含当前值的子数组的最大乘积 & 最小乘积什么时候转…

Linux安装winetim简单教程,[转载]wine安装最新版TIM

[版权声明&#xff1a;本文为转载&#xff0c;并按照个人实际操作步骤替换为了TIM安装&#xff0c;原文为QQ安装过程。]1. 安装wine本次教程只需要安装最新版本的wine&#xff0c;并不需要winetricks、wine-mono、wine-gecko等其他插件&#xff0c;目前经实际测试发现只运行Win…

【LeetCode笔记】283. 移动零(Java)

文章目录题目描述思路 & 代码更新版题目描述 原地操作 & 减少操作次数&#xff1a;不能直接只拷非零数&#xff0c;也不要每次都一个个推动整个数组 思路 & 代码 维护一个noZeroNums&#xff0c;代表当前循环遇到的非0数的数量第一趟先不管0的数量&#xff0c;…

【LeetCode笔记】448. 找到所有不存在的数(Java、原地)

文章目录题目描述思路 & 代码题目描述 说实话&#xff0c;第一眼看题让我想到那道“往1 &#xff5e; 1024中加入一个数&#xff0c;用中学生也会的方法找到这个数"&#xff08;答案是 (1024! x) - 1024! &#xff09;如果没有时空复杂度限制的话&#xff0c;用哈希…

【LeetCode笔记】146. LRU缓存机制(Java、双向链表、哈希表)

文章目录题目描述思路 & 代码LinkedHashMap 的写法题目描述 大名鼎鼎的超高频面试题太感动&#xff0c;在这道题上花了太多时间了&#xff0c;今天终于补上博客了TvT 思路 & 代码 结构用的是&#xff1a;双向链表 哈希表。可以满足O(1)时间复杂度put()&#xff1a…

simulink和c语言开发,Simulink之嵌入式C代码生成-应用层和底层的接口

今天给大家带来的仍然是基于MBD的嵌入式代码生成&#xff0c;主要把应用层和底层接口之间的代码生成配置说一下。本周末会更新功能安全相关&#xff0c;欢迎大家留言交流&#xff01;作为一个总是用C写代码的人来说&#xff0c;第一次接触到基于MBD的代码生成的时候就迫不及待的…

【LeetCode笔记】215. 数组中的第K个最大元素(Java、快排、堆排、并发快排)

文章目录题目描述思路 & 代码快排基于 Fork / Join 的并发快排针对 topK 的快排优化堆排基本堆排结合题目的堆排二刷题目描述 大名鼎鼎的TOP K&#xff0c;主要考察排序快排 & 堆排 思路 & 代码 快排 没啥好说的&#xff0c;就是快排结束后&#xff0c;返回倒…