this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

pkg/math: fix MultipleOf algorithm

math.MultipleOf currently has many false negatives.

The current algorithm functions as follows.
Given math.MultipleOf(x, y):

- use decimal precision of 1
- divide x by y
- check if the resulting apd.Condition is inexact, indicating digits
were discarded

This is incorrect, because any time the result of the quotient
requires more than the provided precision (i.e. 1), we will assume the
result is false.

For example, math.MultipleOf(22, 2) is false because the result is 11,
requiring a precision of 2.

To fix this, the algorithm is adjusted to:

- divide x by y
- return whether the result is an integer, by ensuring the
fractional part is exactly 0

Fixes #2926.

Signed-off-by: Noam Dolovich <noam.tzvi.dolovich@gmail.com>
Change-Id: Ie978ba0880f7260753eb5288b7c0b14de1c9c73c
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1193690
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>

authored by

Noam Dolovich and committed by
Daniel Martí
c8cc4621 1f4927cd

+15 -8
+11 -4
pkg/math/manual.go
··· 114 114 return toInt(&d), err 115 115 } 116 116 117 - var mulContext = internal.BaseContext.WithPrecision(1) 118 - 119 117 // MultipleOf reports whether x is a multiple of y. 120 118 func MultipleOf(x, y *internal.Decimal) (bool, error) { 121 119 var d apd.Decimal 122 - cond, err := mulContext.Quo(&d, x, y) 123 - return !cond.Inexact(), err 120 + 121 + // TODO: It would be preferable to use internal.BaseContext.Rem here, and directly 122 + // check the result for 0. However, this currently fails with "division impossible". 123 + // Fix this when https://github.com/cockroachdb/apd/issues/134 is resolved. 124 + _, err := internal.BaseContext.Quo(&d, x, y) 125 + if err != nil { 126 + return false, err 127 + } 128 + var frac apd.Decimal 129 + d.Modf(nil, &frac) 130 + return frac.IsZero(), nil 124 131 }
+4 -4
pkg/math/testdata/mult.txtar
··· 13 13 14 14 -- out/math -- 15 15 // should be true 16 - t1: false 17 - t2: false 18 - t3: false 19 - t4: false 16 + t1: true 17 + t2: true 18 + t3: true 19 + t4: true 20 20 21 21 // should be false 22 22 f1: false