Fork me on GitHub
#cljs-dev
<
2018-05-18
>
gfredericks01:05:58

cljs.core/mod can give different results from both clojure.core/mod and javascript's %, for integers less than but close to 2^53; is that considered a bug? close meaning same order of magnitude; can be less than 2^52 in fact

gfredericks01:05:14

(mod 4503601479059755 4503601479059764) in particular

favila02:05:01

I think that is unavoidable given long vs doubles

gfredericks02:05:12

it's also inconsistent with the same calculation done using doubles in clj-jvm, and so I assume also doubles in java

gfredericks02:05:40

the cause seems to be some tricks done in cljs.core/mod to deal differently with negative numbers

favila02:05:41

That’s curious, it should be the same

gfredericks02:05:04

so it seems workaroundable, at least in this case, by testing the size of the number

gfredericks02:05:23

example of what? I gave (mod 4503601479059755 4503601479059764) above

favila02:05:30

Those are two Kong’s

gfredericks02:05:42

not in clojurescript

gfredericks02:05:56

add a .0 to test doubles in clj

favila02:05:22

Yes what do you get on clj—I’m not near a real

gfredericks02:05:37

the first arg is smaller by a bit, so the correct answer is to return the first arg

gfredericks02:05:56

everything gets that answer except cljs, which returns, I think, the first arg plus 1

gfredericks02:05:18

due, I assume, to precision lost during the arithmetical tricks

favila02:05:32

Yes but those tricks should be identical to clj

gfredericks02:05:40

I expect clj just defers to the jvm

favila02:05:49

Clj with doubles should be exactly the same as cljs

gfredericks02:05:00

okay so you agree it's a bug then

favila02:05:07

No mod is deliberately not %

gfredericks02:05:30

oh okay, I'm not familiar enough with % then

favila02:05:54

It’s...complicated

gfredericks02:05:54

(defn js-mod
  "Modulus of num and div with original javascript behavior. i.e. bug for negative numbers"
  [n d]
  (cljs.core/js-mod n d))

(defn mod
  "Modulus of num and div. Truncates toward negative infinity."
  [n d]
(js-mod (+ (js-mod n d) d) d))

dpsutton02:05:31

Does the addition push it out of integer range and therefore loses precision?

gfredericks02:05:37

that's my theory

gfredericks02:05:05

I hypothesized based on the reference to negatives in the docstring that those gymnastics shouldn't be necessary for positive numbers

dpsutton02:05:27

Does the js-mod return the correct answer?

dpsutton02:05:35

Wonder how much a branch on positive / negative would impact it? Only need the addition if it's negative?

gfredericks02:05:22

and you'd also have to worry about the very large negative numbers

favila02:05:15

Clj dips into rem, which may use buffer

favila02:05:23

Bigdecimal

dpsutton02:05:53

So there's precision in the type promotion? Which is lacking here?

favila02:05:20

Is a theory

favila02:05:34

I think I have a clj ticket dealing with this

gfredericks02:05:56

I doubt it makes it to the bigdec branch of that code

favila02:05:11

I tried to sort this math out to harmonize clj and cljs once but it’s foggy now

gfredericks02:05:19

floating point numbers drive me nuts

favila02:05:17

Note that the clj impl of mod for doubles never actually uses java %

favila02:05:36

(Which should be same as Js % iirc)

favila02:05:44

No that’s not exactly it

favila02:05:47

I wonder if that impl gives what you expect?

gfredericks03:05:21

which one exactly?

favila03:05:27

Cljs patch

favila03:05:22

No that’s only quot and rem

favila03:05:45

Ah nm I have nothing useful to add. At least not from a iPhone

gfredericks03:05:07

you've added an impressive amount from an iPhone already

favila03:05:40

I am grasping at vague memories of having figured this out

favila03:05:57

But both clj and cljs are a little bit wrong and I don’t remember the details

gfredericks03:05:17

okay, thanks for the pointers. I'm heading to bed

dnolen13:05:52

Putting in some ClojureScript time today let me know if there’s something you want me to look at

dnolen15:05:14

@mfikes https://dev.clojure.org/jira/browse/CLJS-2701, this one doesn’t apply because of CLJS-2751

mfikes15:05:39

OK, will rebaseline.

mfikes15:05:40

Hah, CLJS-2751 and CLJS-2701 are the same defect, fixed in two different ways by me. My memory sucks. 🙂

😜 4
dnolen16:05:36

I suspected that but wasn’t sure