4

How can I round, floor, ceil, and truncate a number in jq jq-1.5-1-a5b5cbe?

For example, with {"mass": 188.72}, I want {"mass": 188} with floor, {"mass": 189} with ceil and round.

Rounding examples:

5.52 --> 6
5.50 --> 5 or 6
-5.52 --> -6

Truncate examples:

5.52 --> 5
5.50 --> 5
-5.52 --> -5

I have come up with -5 as $n | if $n > 0 then [range($n+0.00000000000001)] else [range(-$n)] end | last for truncate, but it is needlessly complex (and likely contains bugs).

peak
  • 105,803
  • 17
  • 152
  • 177
jmpsabisb
  • 182
  • 1
  • 10
  • Whay are you not making use of Math.round, Math.ceil functions? – Nitheesh Nov 27 '19 at 05:27
  • @oguzismail jq-1.5-1-a5b5cbe – jmpsabisb Nov 27 '19 at 05:48
  • @Nitheesh From https://stedolan.github.io/jq/manual/v1.5/#Math: "Availability of standard math functions depends on the availability of the corresponding math functions in your operating system and C math library". Using round, I get `jq: error: round/0 is not defined at , line 1` – jmpsabisb Nov 27 '19 at 05:51

3 Answers3

9

Some builds may lack those functions, but as far as I'm concerned floor is widely available; so, you can implement them using it.

round/0

def round: . + 0.5 | floor;

ceil/0

def ceil: if . | floor == . then . else . + 1.0 | floor end;

trunc/0

def trunc: if . < 0 then ceil else floor end;
oguz ismail
  • 1
  • 16
  • 47
  • 69
5

In jq 1.6 you have access to round/ceil/floor functions

$ echo '{"mass": 188.72}' | jq ' .mass | round '
189
$ echo '{"mass": 188.72}' | jq ' .mass | ceil '
189
$ echo '{"mass": 188.72}' | jq ' .mass | floor '
188
$ 

For jq 1.5, here is the hack

Round:

$ echo '{"mass": 188.42}' | jq ' .mass + 0.5 | tostring | split(".") | .[0] '  -r
188

Ceiling(may have to add more 9999s to increase precision):

$ echo '{"mass": 188.42}' | jq ' .mass + 0.99999999 | tostring | split(".") | .[0] '  -r
189

Floor:

$ echo '{"mass": 188.42}' | jq ' .mass | tostring | split(".") | .[0] '  -r
188
Ke Zhu
  • 207
  • 1
  • 9
1

jq's math builtins are enumerated in the Math section of the jq Manual. The current release is at https://stedolan.github.io/jq/manual/; links to earlier versions are at the top.

Note that both jq 1.5 and 1.6 have builtins named round, ceil, floor and trunc: they are all 0-arity filters.

E.g.

[5.52, 5.50, -5.52 ] | map(trunc)

#=> [5,5,-5]

Earlier versions of jq have different sets of Math functions, e.g. jq 1.4 has floor but not the other three.

peak
  • 105,803
  • 17
  • 152
  • 177
  • I get `jq: error: trunc/0 is not defined at , line 1` – jmpsabisb Nov 27 '19 at 05:49
  • If upgrading doesn't help, see: https://stackoverflow.com/questions/56593531/jq-error-round-0-is-not-defined-at-top-level/56593877#56593877 – peak Nov 27 '19 at 06:18