zoukankan      html  css  js  c++  java
  • Linux下科学计数法(e)转化为数字的方法 [shell中几种数字计算说明]

    科学计数法使用e标识数值,将科学计算学转化为数字的思路按e右边的数字移动小数点位数。e右边的数字如果是负数,则向左移动小数点。示例如下:

    1.2345678e2 = 123.45678
    1.2345678e-2 = 0.012345678
    1.7615562e+06 = 1761556.2
    1.87982e7 = 18798200
    1e3 = 1000
    

    那么在shell中,如何转化科学计数法为数字呢,方法如下:这里以"1.7615562e+06" (或者1.7615562e6)为示例:

    [root@kevin ~]# echo "1.7615562e6"| gawk '$1=strtonum($1)'
    1.76156e+06
    

    1)科学计数法转为十进制

    [root@kevin ~]# printf "%f" 1.7615569e+06
    1761556.900000
     
    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%f",$0)}'   
    1761556.900000
    
    [root@kevin ~]# echo "1.7615569e+03"| awk '{printf("%f",$0)}' 
    1761.556900
    
    [root@kevin ~]# echo "1.7615569e+04"| awk '{printf("%f",$0)}' 
    17615.569000
    
    [root@kevin ~]# echo "1.7615569e-6"| awk '{printf("%f",$0)}' 
    0.000002
    
    [root@kevin ~]# echo "1.7615569e-4"| awk '{printf("%f",$0)}' 
    0.000176
    
    [root@kevin ~]# echo "1.7615569e-3"| awk '{printf("%f",$0)}' 
    0.001762
    
    [root@kevin ~]# echo "1.7615569e-2"| awk '{printf("%f",$0)}' 
    0.017616
    
    需要注意: 这种方法,转化结果中小数点后面都保留6位:
    1)e后面的数字若是正数,则小数点后面要保留6位,不够的话,用0补上。
    2)e后面的数字若是负数,则小数点后面要保留6位,多的话,此时按照四舍五入,保留6位。

    2)科学计数法转为十进制并保留两位小数

    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%.2f",$0)}'    
    1761556.90
    
    保留三位小数
    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%.3f",$0)}'    
    1761556.900
    

    3)科学计数法转为十进制并取整

    [root@kevin ~]# echo "1.7615569e+06"|awk '{printf("%d",$0)}'   
    1761556
    
    [root@kevin ~]# echo "1.7615569e3"|awk '{printf("%d",$0)}'     
    1761
    
    [root@kevin ~]# echo "1.7615569e02"|awk '{printf("%d",$0)}'   
    176
    

    4)科学计数法转十进制并四舍五入取整

    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%d",$0+0.5)}'  
    1761557
    
    [root@kevin ~]# echo "1.7615563e+06"| awk '{printf("%d",$0+0.5)}'  
    1761556
    

    《扩展1》                                                                                                                                                    
    5)如何将小数点后无用的0去掉, 可以参考: 日常运维的Shell脚本中截取字符串的做法,即用变量扩展的方式

    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%f",$0)}' 
    1761556.900000
    
    [root@kevin ~]# var=$(echo "1.7615569e+06"| awk '{printf("%f",$0)}')
    [root@kevin ~]# echo ${var%%0*}
    1761556.9
    

    或者使用sed方法也可以

    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%f",$0)}'      
    1761556.900000
     
    [root@kevin ~]# var=$(echo "1.7615569e+06"| awk '{printf("%f",$0)}')
    [root@kevin ~]# echo "$var"|sed 's/0*$//'
    1761556.9
    
    [root@kevin ~]# echo "1.7615569e+06"| awk '{printf("%f",$0)}'| sed 's/0*$//'
    1761556.9

    《扩展2》                                                                                                                                                    
    6)sed去除掉小数点之后的字符

    [root@kevin ~]# echo "kevin.123"|sed "s/.*//g"
    kevin123
    
    ..*代表了小数点之后的1到多个
    [root@kevin ~]# echo "kevin.123"|sed "s/..*//g"
    kevin
    
    
    [root@kevin ~]# echo "kevin_123"|sed "s/\_*//g"
    kevin123
    
    [root@kevin ~]# echo "kevin_123"|sed "s/\_.*//g"
    kevin
    
    命令解释:
    *代表0到多个。故.*只能替换掉小数点变成空。\_*同理。
    .*代表1到多个。故..*将小数点后的全部去掉了。\_.*同理。
    

    《扩展3》                                                                                                                                                   
    7)shell中的数字计算说明

    1)bc方法
    bc是比较常用的linux计算工具了,而且支持浮点运算:
    [root@kevin ~]# a=`echo 1+1 | bc`
    [root@kevin ~]# echo $a
    2
     
    这种方法没法解决浮点数运算的精度问题,如下几种浮点数计算情况就傻X了!
    [root@kevin ~]# a=`echo 1+1 | bc`
    [root@kevin ~]# echo $a
    2
    [root@kevin ~]# b=`echo "1.2*1.2" | bc`
    [root@kevin ~]# echo $b
    1.4
    [root@kevin ~]# c=`echo "5.0/3.0" | bc`
    [root@kevin ~]# echo $c
    1
    [root@kevin ~]# d=`echo "scale=2;5.0/3.0" | bc`
    [root@kevin ~]# echo $d
    1.66
    [root@kevin ~]# e=`echo "scale=2;5.0/6.0" | bc`
    [root@kevin ~]# echo $e
    .83
     
    2)expr方法
    不支持浮点数计算,这是个坑,而且要注意数字与运算符中的空格。
    [root@kevin ~]# a=`expr 1+1`
    [root@kevin ~]# echo $a
    1+1
    [root@kevin ~]# a=`expr 1 + 1`
    [root@kevin ~]# echo $a
    2
    [root@kevin ~]# b=`expr 10 / 2`
    [root@kevin ~]# echo $b
    5
     
    3)$(())方法
    同expr,不支持浮点数运算
    [root@kevin ~]# a=$((1+1))
    [root@kevin ~]# echo $a
    2
    [root@kevin ~]# b=$((1 + 3 ))
    [root@kevin ~]# echo $b
    4
     
    4)let方法
    不支持浮点数运算,而且不支持直接输出,只能赋值
    [root@kevin ~]# let a=1+1
    [root@kevin ~]# echo $a
    2
    [root@kevin ~]# let b=50/5
    [root@kevin ~]# echo $b
    10
    [root@kevin ~]# let c=1.2*2
    -bash: let: c=1.2*2: syntax error: invalid arithmetic operator (error token is ".2*2")
     
    5)awk方法
    普通的运算:
    [root@kevin ~]# a=`echo | awk '{print 1.0/2.0}'`
    [root@kevin ~]# echo $a
    0.5
     
    控制精度:
    [root@kevin ~]# b=`echo | awk '{printf("%.2f",1.0/2.0)}'`
    [root@kevin ~]# echo $b
    0.50
     
    传递参数:
    [root@kevin ~]# c=`echo | awk -v a=1 -v b=3 '{printf("%.4f",a/b)}'`
    [root@kevin ~]# echo $c
    0.3333
    
    awk结合BEGIN(小数点后面保留6位)
    [root@ss-server ~]# awk 'BEGIN{printf "%.2f%%
    ",(87/500)*100}'
    17.40%
    [root@ss-server ~]# awk 'BEGIN{printf "%.2f%%
    ",(100/300)*100}'
    33.33%
     
    综合来看,还是awk的方法最靠谱,其他的方式都有相应问题。所以推荐在日常维护场景下使用awk来搞数学计算。
  • 相关阅读:
    阿里terway源码分析
    golang timeoutHandler解析及kubernetes中的变种
    第四章 控制和循环
    关于 自媒体的声明
    java用正则表达式获取url的域名
    javaweb三大核心基础技术
    NumPy之计算两个矩阵的成对平方欧氏距离
    C/C++之计算两个整型的平均值
    C/C++代码优化之整型除以2的指数并四舍五入
    SSE系列内置函数中的shuffle函数
  • 原文地址:https://www.cnblogs.com/kevingrace/p/11643869.html
Copyright © 2011-2022 走看看