jaq icon indicating copy to clipboard operation
jaq copied to clipboard

regression (jaq 1.6 gave correct answer)

Open pkoppstein opened this issue 1 year ago • 4 comments

Presumably there's an explanation for why jaq 1.6 gave the correct answer for a particular problem at https://rosettacode.org/wiki/Sum_multiples_of_3_and_5#jq (reproduced below), whereas jaq 2.0.0 gives a very different (incorrect) answer, but is it a sufficiently good one?

$ ./jaq --version
jaq 1.6.0
2.333333333333333e41

$ jaq --version
jaq 2.0.0
-4.611686018427388e18

##########################

def sum_multiples(d):
 ((./d) | floor) |  (d * . * (.+1))/2 ;

# Sum of multiples of a or b that are less than . (the input)
def task(a;b):
 . - 1
 | sum_multiples(a) + sum_multiples(b) - sum_multiples(a*b);

(10e20 | task(3;5))

pkoppstein avatar Nov 30 '24 21:11 pkoppstein

Tried to minimize it down a bit:

$ jaq -n '1e20/2 | floor, trunc'
9223372036854775807
5e19
$ jq -n '1e20/2 | floor, trunc'
5e+19
5e+19
$ gojq -n '1e20/2 | floor, trunc'
50000000000000000000
50000000000000000000

with 1e19/2 they all agree

wader avatar Dec 01 '24 19:12 wader

I currently do not know why jaq 1.6 seems to output the correct answer, but when you change floor to trunc in your program, then jaq 2.0 also outputs the result 2.333333333333333e41. Why? round, floor, and ceil convert their inputs to integers, but the size of the numbers here is too large for integers --- so we get an overflow, which is why jaq 2.0 outputs a negative number with floor.

As a rule of thumb: When you treat numbers that might not fit into machine-size integers, then use trunc to round them. Otherwise, use round, floor, and ceil.

01mf02 avatar Dec 02 '24 12:12 01mf02

I currently do not know why jaq 1.6 seems to output the correct answer.

I wonder if this was also due to https://github.com/01mf02/jaq/pull/219 lol?

null-dev avatar Dec 02 '24 23:12 null-dev

@null-dev, your hypothesis looks quite plausible!

01mf02 avatar Dec 03 '24 16:12 01mf02