如何在LinuxBash中将十进制转换为指数
可以用指数变换十进制数吗 11.2345转化为0.112345E+2如何在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
谢谢您使用
printf
命令它允许您提供一种格式,就像在Cprintf
的情况下一样,您有一个%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、 例如,
- 输出数字总是使用标准化科学符号,其中有效位(
/e
之前的数字)具有整数部分e
和=1
,指数始终是带明确符号的两位(十进制)整数:<9
- e、 例如,
产生printf%.1e 66
(在英语区域设置中)6.6e+01
- 无法对有效位应用不同的规范化,例如以
(如问题中所用)0开头。
- e、 例如,
尊重当前区域设置,这意味着输入数字和输出都必须按照当前区域设置的规则格式化,特别是小数点(printf%e
vs.
)和千位分隔符(,
vs.,
vs.
)- e、 例如,
使用德语语言环境生成(export LC_ALL=de_de.UTF-8;printf%.2e 66,1)
,注意在输入和输出中使用6,61e+01
作为小数点,
- e、 例如,
在底部找到支持区域设置的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"
}