bash - 如何让 bc 以科学(又名指数)表示法处理数字?

标签 bash numeric floating-accuracy bc

bc 不喜欢用科学计数法(又名指数计数法)表示的数字。

$ echo "3.1e1*2" | bc -l
(standard_in) 1: parse error

但我需要用它来处理一些用这种表示法表示的记录。有没有办法让 bc 理解指数表示法?如果不是,我该怎么做才能将它们翻译成 bc 能够理解的格式?

最佳答案

很遗憾,bc 不支持科学记数法。

但是,可以使用extended regex as per POSIX 将其翻译成bc 可以处理的格式。在 sed 中:

sed -E 's/([+-]?[0-9.]+)[eE]\+?(-?)([0-9]+)/(\1*10^\2\3)/g' <<<"$value"

您可以将“e”(或“e+”,如果指数为正)替换为“*10^”,bc 会立即理解。即使指数为负,或者如果数字随后乘以另一个幂,这也有效,并允许跟踪有效数字。

如果您需要坚持使用基本正则表达式 (BRE),那么应该使用:

sed 's/\([+-]\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}\)[eE]+\{0,1\}\(-\{0,1\}\)\([0-9]\{1,\}\)/(\1*10^\2\3)/g' <<<"$value"

来自评论:

  • 一个简单的 bash pattern匹配无法工作(感谢 @mklement0),因为无法同时匹配 e+ 和保留 e- 中的 -。

  • 正确工作的 perl 解决方案(感谢 @mklement0)

    $ perl -pe 's/([-\d.]+)e(?:\+|(-))?(\d+)/($1*10^$2$3)/gi' <<<"$value"
    
  • 感谢 @jwpat7@Paul Tomblin用于阐明 sed 语法的各个方面,以及 @isaac@mklement0用于改进答案。

编辑:

多年来,答案发生了很大变化。上面的答案是截至 2018 年 5 月 17 日的最新迭代。此处报告的先前尝试是纯 bash 中的解决方案(作者 @ormaaj )和 sed 中的解决方案(作者 @me ),至少在某些情况下失败了。我将它们保留在这里只是为了让评论有意义,这些评论包含比这个答案更好的对所有这些复杂性的解释。

value=${value/[eE]+*/*10^}  ------> Can not work.
value=`echo ${value} | sed -e 's/[eE]+*/\\*10\\^/'` ------> Fail in some conditions

关于bash - 如何让 bc 以科学(又名指数)表示法处理数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12882611/

相关文章:

PHP Printf 作为浮点精度

clojure - Clojure 中的浮点精度

bash - 连接无法连接整个文件

linux - 在 Bash 函数中优化多行管道到 Awk

bash - 将 SSH 流作为 Perl 脚本输入而不是物理文件

MySQL:如果值仅为数字则更新列

python - 将 bash/python 脚本与 Selenium 集成

带数字键的 PHP array_merge_recursive

c++ - DBL_MIN 是最小的正 double 吗?

Golang 浮点运算