【问题标题】:define format of printf "%E"定义 printf "%E" 的格式
【发布时间】:2023-03-25 03:50:01
【问题描述】:

我在编写一个 bash 脚本,并希望将一个始终为整数的输入值转换为科学记数法。 例如,当我使用 printf "%E" 时,300 的值将转换为 3.00E+02。原则上这是有道理的,但我需要特殊格式 0.300E+03。我没有找到管理它的方法。 感谢您的帮助。

问候 地狱

【问题讨论】:

    标签: bash printf scientific-notation


    【解决方案1】:

    一种粗鲁的方式,只是开始... 警告:这仅适用于您的示例,尾数和指数为正:

    #!/bin/sh
    
    theval=$(printf "%4.2E" "$1")   # 200 -> 2.00E+02
    # we want 0.  20  E+03
    
    mantissa=${theval%E*}
    echo "mantissa1=$mantissa"  # 2.00
    mantissa="0.${mantissa:0:1}${mantissa:2:1}"
    echo "mantissa2=$mantissa"
    
    exp=${theval#*+}
    let exp=exp+1
    exp=$(printf "%2.2d" $exp)
    
    echo "Result=${mantissa}E+$exp"
    

    运行此脚本会产生:

    /tmp$ ./exp.sh 200
    mantissa1=2.00
    mantissa2=0.20
    Result=0.20E+03
    

    【讨论】:

      【解决方案2】:

      来自man 3 printf,强调我的:

      e, E double 参数被四舍五入并转换为[-]d.ddde±dd 样式,其中小数点字符前有一位,其后的位数等于精度;如果精度缺失,则取6;如果精度为零,则不出现小数点字符。 E 转换使用字母 E(而不是 e)来引入指数。指数始终包含至少两位数字;如果值为零,则指数为 00。

      如果您希望尾数介于 0 和 1 之间,则需要构建自己的格式化程序。这是awk 中的一个示例。处理 0 和负数:

      function sn() {
          awk -vn=$1 'BEGIN {
          split(n,a,"E");
          if      (0 < a[1]) { m=a[1]/10; e=a[2]+1; p=length(a[1])-1; }
          else if (a[1] < 0) { m=a[1]/10; e=a[2]+1; p=length(a[1])-2; }
          else               { m=0; e=0; p=length(a[1])-2; }
          printf "%0.*fE%+03d", p, m, e;
          }'
      }
      

      像这样使用:

      sn $(printf "%4.2E" -0.024)
      

      【讨论】:

        【解决方案3】:

        感谢您的回答。 原则上它是有效的,但是当我有一个像 3180 这样的数字时,只考虑数字的第一个字段 3,而不是初始数字的其余部分。我将尝试找出定义字段数的代码部分。

        问候 地狱

        【讨论】:

        • 我用 3180 尝试了我的答案,它几乎可以正常工作。 您在此处的回答应该作为评论发布,而不是作为答案发布
        猜你喜欢
        • 1970-01-01
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-01
        • 2010-10-06
        • 2012-08-05
        • 2010-11-12
        相关资源
        最近更新 更多