如何在LinuxBash中将十进制转换为指数

如何在LinuxBash中将十进制转换为指数,bash,decimal,exponential,Bash,Decimal,Exponential,可以用指数变换十进制数吗 11.2345转化为0.112345E+2 谢谢您使用printf命令它允许您提供一种格式,就像在Cprintf的情况下一样,您有一个%e选项,它以指数表示法打印: printf %e 11.2345 这将导致: 1.123450e+01 有助于建议使用printf“%e”,但这有以下含义: 注意:printf“%E”的工作原理基本相同,只是它在输出中使用大写的E 默认情况下,它在输出中使用6位小数位,而不管输入数字有多少位有效数字 e、 例如,printf%e

可以用指数变换十进制数吗

11.2345转化为0.112345E+2


谢谢您

使用
printf
命令它允许您提供一种格式,就像在C
printf
的情况下一样,您有一个
%e
选项,它以指数表示法打印:

printf %e 11.2345
这将导致:

1.123450e+01
有助于建议使用printf“%e”,但这有以下含义:

注意:
printf“%E”
的工作原理基本相同,只是它在输出中使用大写的
E

  • 默认情况下,它在输出中使用6位小数位,而不管输入数字有多少位有效数字

    • e、 例如,
      printf%e1
      产生
      100000e+00
    • 您可以显式控制输出小数位数:
      • e、 例如,
        printf%.1e 129
        产生
        1.3e+02
    • 但是,没有任何机制可以使用与输入数字相同的有效数字
  • 输出数字总是使用标准化科学符号,其中有效位(
    e
    /
    e
    之前的数字)具有整数部分
    =1
    <9
    指数始终是带明确符号的两位(十进制)整数:

    • e、 例如,
      printf%.1e 66
      产生
      6.6e+01
      (在英语区域设置中)
    • 无法对有效位应用不同的规范化,例如以
      0开头。
      (如问题中所用)
  • printf%e
    尊重当前区域设置,这意味着输入数字和输出都必须按照当前区域设置的规则格式化,特别是小数点(
    vs.
    )和千位分隔符(
    vs.
    vs.

    • e、 例如,
      (export LC_ALL=de_de.UTF-8;printf%.2e 66,1)
      使用德语语言环境生成
      6,61e+01
      ,注意在输入和输出中使用
      作为小数点

在底部找到支持区域设置的Bash函数
toNumSci()
,它解决了其中的一些限制;特别是,它允许您保留有效输入位数,并选择
0.d..
有效位规范化

应用于问题中的示例,您将使用:

$ toSciNum 11.2345 1 # 1 opts into `0.d...` significand normalization
0.112345E+02 # same number of significant digits, 0.d...-normalized
注意:与问题输出格式的唯一不同之处是使用了两位数的左填充零指数

toNumSci()的源代码


试试看:
printf“%e”11.2345
Hat off to a slick implementation。
#!/usr/bin/env bash

# Usage:
#   toSciNum number [zeroDotFormat [numSigDigits]]
# Converts the specified number (float or integer) to normalized scientific 
# notation ([+-]d.d...E+-dd), preserving the number of significant digits in 
# the input.
# Optionally you can control the number of significant digits explicitly
# and choose alternative output format [+-]0.d...E+-dd
# Note: The input number must use locale-appropriate formatting with
#       respect to decimal mark and thousands grouping, if applicable.
#       Similarly, the output number is formatted locale-appropriately. 
# Examples:
#   toSciNum 123    # -> 1.23E+02
#   toSciNum 123 1  # -> 0.123E+03
#   toSciNum -66.7 0 4  # -> -6.670+01
toSciNum() {

  local num=$1 zeroDotFormat=${2:-0} numSigDigits=$3
  local digitsOnly fmtStr numSci decMark significand exponent sign=

  # Determine the number of significant digits.
  # If not specified, use the same number as in the input number.
  if [[ -z $numSigDigits ]]; then
    digitsOnly=${num//[!0-9]} # Remove all non-digit characters...
    numSigDigits=${#digitsOnly} # ... and count them.
  fi

  # Construct the printf format string.
  # Note that the number of decimal places is the number of
  # significant digits minus 1, because in the normalized scientific notation
  # that %e / %E produce, there by definition always 1 integer digit. 
  fmtStr="%.$(( numSigDigits - 1 ))E"

  # Create the normalized scientific notation representation (d.dddd ...) 
  # and store it in var. $numSci.
  printf -v numSci "$fmtStr"  "$num"

  # If the 0.ddd format is requested instead, transform the result.
  if (( zeroDotFormat )); then
    [[ $numSci == -* ]] && sign='-'
    # Extract the decimal mark from the result.
    decMark=${numSci:1:1}
    # Extract the exponent from the result
    significand=${numSci%E*}
    exponent=${numSci##*E}
    # Construct the new significand as [-]0.ddd
    significand="${sign}0${decMark}${significand//[!0-9]}"
    # Construct the new exponent (to which +1 must be added to compensate, now 
    # that the significand is effectively being divided by 10.
    printf -v exponent '%+03d' $(( 1 + 10#${exponent} ))
    # Assemble the pieces to form the new number.
    numSci="${significand}E${exponent}"
  fi

  printf '%s\n' "$numSci"
}