【问题标题】:In jq, how to get tonumber to output decimal instead of scientific notation在jq中,如何让tonumber输出十进制而不是科学计数法
【发布时间】:2018-09-05 05:27:00
【问题描述】:

在 JSON 对象中,给定字符串 "0.0000086900" 作为键值对的值,如果我对此执行 |tonumber,则返回 8.69e-06

如何确保只返回小数? 在上述情况下,这将是 0.0000086900

解决方案(基于以下 Peak 的代码 sn-p)

def to_decimal:
  def rpad(n): if (n > length) then . + ((n - length) * "0") else . end;
  def lpad(n): if (n > length) then ((n - length) * "0") + . else . end;

tostring
  | . as $s
  | [match( "(?<sgn>[+-]?)(?<left>[0-9]*)(?<p>\\.?)(?<right>[0-9]*)(?<e>[Ee]?)(?<exp>[+-]?[0-9]+)" )
      .captures[].string] as [$sgn, $left, $p, $right, $e, $exp]
  | if $e == "" then .
    else ($exp|tonumber) as $exp
    | ($left|length) as $len
    | if $exp < 0 then "0." + ($left | lpad(1 - $exp - $len)) + $right
      else ($left | rpad($exp - $len)) + "." + $right
      end
      | $sgn + .
    end;

【问题讨论】:

标签: json string decimal jq scientific-notation


【解决方案1】:

不幸的是,目前 jq 中没有办法像这样修改 JSON 数字的表示;最好的办法是将它们的表示修改为字符串。这是可以做什么的简单说明。

to_decimal 将 JSON 数字(或数字的有效 JSON 字符串表示形式,可能带有前导“+”)作为输入,并将其转换为合适的字符串,例如:

["0","1","-1","123","-123",".00000123","1230000","-.00000123","-0.123","0.123","0.001"]

产生:

[0,"0"]
["+1","1"]
[-1,"-1"]
[123,"123"]
[-123,"-123"]
[1.23e-06,".00000123"]
[1230000,"1230000"]
[-1.23e-06,"-.00000123"]
[-0.123,"-0.123"]
[0.123,"0.123"]
[0.001,"0.001"]

请注意,任何前导的“+”都会被删除。

to_decimal

def to_decimal:
  def rpad(n): if (n > length) then . + ((n - length) * "0") else . end;
  def lpad(n): if (n > length) then ((n - length) * "0") + . else . end;

  tostring
  | . as $s
  | capture( "(?<sgn>[+-]?)(?<left>[0-9]*)(?<p>\\.?)(?<right>[0-9]*)(?<e>[Ee]?)(?<exp>[+-]?[0-9]+)" )
  | if .e == "" then (if .sgn == "+" then $s[1:] else $s end)
    else (.left|length) as $len
    | (.exp|tonumber) as $exp
    | (if .sgn == "-" then "-" else "" end ) as $sgn
    | if $exp < 0 then "." + (.left | lpad(1 - $exp - $len)) + .right
      else (.left | rpad($exp - $len)) + "." + .right
      end
      | $sgn + .
    end ;

【讨论】:

  • 在许多情况下您的功能无法正常工作,例如-1.23e-6。我已经修复了这个问题,以及拼写错误 [+=] -> [+-],以及仅使用小数的小数标准化(我们有 .45 -> 0.45 但 1.23e-6 -> .00000123。现在所有纯小数以“0.”开头,包括负数)。
  • @John S. -- 感谢您指出错字,已修复。我相信所有其他问题也已得到解决。
猜你喜欢
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
  • 2011-06-16
相关资源
最近更新 更多