jq
jq copied to clipboard
is there way to convert scientific notation numbers to fixed length float
I have numbers like this 1.26126e-06 in JSON that I would like to convert to 'normal' looking floats (e.g 0.00000126126). Is there an equivalent to printf or JavaScript's toFixed()?
Or is there some other way to set the precision.
At least something like an option to convert float to int dropping the remainder. Then we could at least mock mynumber.toFixed(2) with (mynumber*100 | toInteger) / 100.
I'd like a command line argument to specify the number of digits. FWIW you can do this using Miller (mlr):
$ mlr --json format-values -f '%.9f' <<<'{"x": 1.26126e-6}'
{ "x": 0.000001261 }
@sjackman mlr --json format-values ... will not handle JSON array correctly (members are pulled out)
Yeah, Miller handles only tabular JSON files AFAIK.
@MarSoft This works right now: .*100 | floor | ./100.
$ jq '.*100 | floor | ./100' <<<'{"hi": "Hello, world!", "frac": 123.456}'
jq: error (at <stdin>:1): object ({"hi":"Hell...) and number (100) cannot be multiplied
@sjackman jq '(.. | numbers) |= (.*100 | floor | ./100)' <<<'{"hi": "Hello, world!", "frac": 123.456789}'
That works! Thanks, @itchyny! As a feature request, round could optionally take an accuracy parameter such as round(0.01).
@sjackman You can substitute floor with round in my suggestion to get the effect you want:
$ jq '.*100 | round | ./100' <<< 123.456789
123.46
$ jq '(.. | numbers) |= (.*100 | round | ./100)' <<<'{"hi": "Hello, world!", "frac": 123.456789}'
{
"hi": "Hello, world!",
"frac": 123.46
}
And also define the function you seek:
$ jq 'def round(p): .*(1/p) | round | ./(1/p); round(0.01)' <<< 123.456789
123.46
@sjackman You can substitute
floorwithroundin my suggestion to get the effect you want:$ jq '.*100 | round | ./100' <<< 123.456789 123.46 $ jq '(.. | numbers) |= (.*100 | round | ./100)' <<<'{"hi": "Hello, world!", "frac": 123.456789}' { "hi": "Hello, world!", "frac": 123.46 }And also define the function you seek:
$ jq 'def round(p): .*(1/p) | round | ./(1/p); round(0.01)' <<< 123.456789 123.46
can this be adjusted to work with larger numbers?
$ jq 'def round(p): .*(1/p) | round | ./(1/p); round(0.00001)' <<< 0.00004948914415535700
5.000000000000001e-05
@arno01 You can simplify the expressions I used. I used those because they seemed clearer to me, but if you limit the operations used, that decreases chances of floating-point rounding errors:
$ jq 'def round(p): ./p | round | .*p; round(0.00001)' <<< 0.00004948914415535700
5e-05
@arno01 You can simplify the expressions I used. I used those because they seemed clearer to me, but if you limit the operations used, that decreases chances of floating-point rounding errors:
$ jq 'def round(p): ./p | round | .*p; round(0.00001)' <<< 0.00004948914415535700 5e-05
I'd love to get rid of scientific notation though..
if it could turn 0.00004948914415535700 into 0.0000495 that'd be neat :)
@arno01 Adding that to jq is what this issue is about. In the mean time, converting that scientific notation would have be done outside. For example, like this:
$ printf '%.7f\n' "$(jq 'def round(p): ./p | round | .*p; round(0.0000001)' <<< 0.00004948914415535700)"
0.0000495
needed here as well
$ echo '{}' | jq '0.1 + 0.2 | .*100 | floor | ./100'
0.3
The expected result should be 0.30