shell的计算什么时候会有小数?什么时候是整数

来源:互联网 发布:淘宝网京东商城童装 编辑:程序博客网 时间:2024/04/27 14:36

最近的脚本因为涉及到一些计算,比方乘以80%,乘以1.2,除以80%这种的,有时候希望能得到小数,有时候希望结果是截断小数的,但是实际计算的时候还是迷迷糊糊的,所以特此整理一下。

1.首先来几个实验验证一下:

bc下的数学计算

从上面这个图中可以看到,在bc的交互命令模式下:
1+2=3
1*0.8=.8  这里还是希望结果是0.8
10*1.23=12.3
1/5=0
22/5=4  整数的除法是截断的,24/5=4.8,截断之后仍然是4,有时候我们会希望四舍五入,有时候我们希望保留两位小数。
继续了解一下,会有
0.8/2 =0
1/0.8 =1
1*5/4=1
这些结果。


那我们开始解决一些疑问吧:
1.1/0.8=.8如何得到0.8的结果?
2.1/5=0如何得到0.2的结果?
324/5=4如何得到5的结果(四舍五入)?
4.1/3=0如何得到0.33的结果(保留两位小数)?



首先,bash只支持整型运算,但可以使用bc,awk和nawk工具来处理更复杂的运算。

1.scale … |bc 方式可以指定保留小数位数

[root@db22 ~]# echo "scale=2;1/5"|bc.20[root@db22 ~]# echo "scale=2;24/5"|bc4.80

说明: echo命令的输出通过管道传送给bc程序。变量scale赋值为2,表示小数点后的有效位数为2。bc 来计算1除以5的值

2.awk的方式

[root@db22 ~]# echo `awk -v x=1 -v y=5 'BEGIN{printf "%.2f\n",x/y}'`0.20

说明:通过命令行传递参数列表,gawk从该列表中获取参数值:x=2.45,y=3.123。乘法运算完成后,printf函数格式化并显示运算结果,保留小数点后两位数,并将输出赋给变量product。

2.1 printf的格式化输出

上面代码中的%.2f 被称为格式符(format specifier)。格式符由以下几部分组成:

%[flags][width][.precision]conversion    %  -      5      .2         f  
  • %是必须的, 任何格式符都由百分号开始
  • flags 是可选的,详见下表
  • width 是可选的, 表示输出的宽度
  • precision 可选的, precision 依赖于 conversion, 详见下表.
  • conversion 是必须的, 表示如何格式化参数, 详见下表

awk 支持如下转换符(conversion)。

转换符 描述 c ASCII 字符 (打印第一个字符) d 十进制整数 i 十进制整数 e 浮点数科学计数法 E 浮点数科学计数法 f 浮点数 g %e 或 %f, 取决于哪个更短, 删除尾部0 G %E 或 %f, 取决于哪个更短, 删除尾部0 u 无符号十进制整数 o 无符号八进制整数 x 无符号十六进制整数(a-f for 10 to 15) X 无符号十六进制整数(A-F for 10 to 15) %% % s 字符串

awk 支持如下标志(flag)

标志 描述 举例 - 左对齐 [3333.33] 空格 在正数之前添加空格 [ 3333.33],[-3333.33] + 打印正负数符号 [+3333.33],[-3333.33] 0 数字前面补0 [003333.33] (对于%o) 添加前缀0 [0515] (对于%x) 添加前缀0x [0x1bc] (对于%X) 添加前缀0X [0X1bc] (对于%e) 添加小数点 [1.000000e+01] (对于%E) 添加小数点 [1.000000E+01] (对于%f) 添加小数点 echo awk -v x=1 -v y=5 'BEGIN{printf "%#f\n",x*y}'结果: [5.000000] (对于%g) 不删除尾部0 [10.4000] (对于%G) 不删除尾部0 [10.4000]

awk 精度(precision)的意义

转换符 精度意义 %d,%i,%o,%u,%x,%X 最少数字位数,如果数字位数少于精度,添加前缀0 %e, %E 最少数字位数,如果数字位数少于精度,添加后缀0 %f 小数的位数 %g, %G 最多数字位数 %s 字符位数

sprintf 函数

如果你不想打印,而是想格式化一个字符串,然后把它保存到一个变量中,该怎么办呢?试一试 sprintf 函数吧。

#! /usr/bin/awk -fBEGIN {    str=sprintf("%5.2f", 33.698);    print str;};{};END {};

利用已经习得的命令来解决我们在一开始提出的4个问题


那我们开始解决一些疑问吧:
1.1/0.8=.8如何得到0.8的结果?
2.1/5=0如何得到0.2的结果?
324/5=4如何得到5的结果(四舍五入)?
4.1/3=0如何得到0.33的结果(保留两位小数)?

四舍五入的这个可以在结果上+0.5来达到。

参考文档:

shell脚本中小数的计算

Linux学习4之shell脚本中的小数运算

awk格式化输出









原创粉丝点击