2016-07-22 3 views

ответ

3

Использование printf команды это позволяет обеспечить форматирование, как и в случае C printf, там у вас есть %e вариант, который печатает в экспоненциальной нотации:

printf %e 11.2345 

Этот приведет к:

1.123450e+01 
1

krzyk's answer услужливо предлагает использовать printf '%e', но это имеет следующие последствия :

Примечание: printf '%E' в основном работает так же, за исключением того, что он использует прописнуюE на выходе.

  • Он использует знаков после запятой в выводе по умолчанию, независимо от того, сколько значащих цифр ввода цифр не были.

    • например, printf %e 1 дает 1.000000e+00
    • Вы можете контролировать количество выходных знаков после запятой явно:
      • например, printf %.1e 129 урожайности 1.3e+02
    • Однако есть no, чтобы использовать точно столько же значащих цифр, сколько входной номер имеет.
  • Номер вывода неизменно использует нормализуется научной нотации, где мантисса (число перед e/E) имеет целую часть >= 1 и < 9 и показатель всегда двух- (десятичное) целое число с явным знаком:

    • eg, printf %.1e 66 дает 6.6e+01 (в английской локализации)
    • Существует нет способа применить разных нормализацию для мантиссы, например, начиная его с 0. (как и в вопросе).
  • printf %e уважает текущего стандарта, что означает, что как число вход должен быть - и на выходе будет - отформатированы в соответствии с правилами текущего стандарта, в частности в отношении десятичного знака (. против ,) и разделителем тысяч (, против . против <space>).

    • например, (export LC_ALL=de_DE.UTF-8; printf %.2e 66,1) дает 6,61e+01, используя немецкий языковой стандарт - обратите внимание на использование , в качестве десятичного знака в обоих входных и выходных.

Найти локаль-Aware функция 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():

#!/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" 
} 
+1

Hat прочь к гладкой реализации. –