简体   繁体   English

jqwik双生成器不能用比例表示

[英]jqwik double generator cannot be represented with scale

when using "chained" double generators with jqwik I get a scale error message java.util.concurrent.ExecutionException: net.jqwik.api.JqwikException: Decimal value -1.6099999999999999 cannot be represented with scale 4. .当使用带有 jqwik 的“链式”双生成器时,我收到一条比例错误消息java.util.concurrent.ExecutionException: net.jqwik.api.JqwikException: Decimal value -1.6099999999999999 cannot be represented with scale 4. .

Can you provide me with some details on how to set this scale and the meaning of this parameter ?您能否提供一些有关如何设置此比例以及此参数含义的详细信息?

Here is the generator function I use :这是我使用的生成器函数:

    @Provide("close doubles")
    Arbitrary<Tuple.Tuple2<Double,Double>> closeDoubles(@ForAll() Double aDouble) {
        return Arbitraries.doubles()
                .between(aDouble-2.5, aDouble+2.5)
                .withSpecialValue(aDouble)
                .ofScale(4)
                .map(num ->Tuple.of(aDouble,num));
    }

It is then combined to form a business object instance.然后将其组合成一个业务对象实例。

My ultimate goal is to generate 2 doubles that are "close" to each other (here the distance is 2.5).我的最终目标是生成两个彼此“接近”的双打(这里的距离是 2.5)。

The problem you encounter is due to rounding errors of double numbers and the fact that jqwik is strict with allowing only upper and lower boundaries that comply with the specified scale.您遇到的问题是由于双数的舍入错误以及 jqwik 严格只允许符合指定比例的上下边界的事实。

I see several options to get around that, one is to use BigDecimals for generation and map them to double afterwards.我看到了几种解决方法,一种是使用 BigDecimals 进行生成,然后将它们映射为加倍。 This may look like overhead but actually it is not because that's what jqwik is doing anyway under the hood.这可能看起来像开销,但实际上并不是因为这就是 jqwik 在幕后所做的事情。 This could look like:这可能看起来像:

@Provide
Arbitrary<Tuple.Tuple2<Double, Double>> closeDoubles(@ForAll @Scale(4) BigDecimal aBigDecimal) {
    BigDecimal twoPointFive = new BigDecimal("2.5");
    return Arbitraries.bigDecimals().between(aBigDecimal.subtract(twoPointFive), aBigDecimal.add(twoPointFive))
                      .ofScale(4)
                      .map(num -> Tuple.of(aBigDecimal.doubleValue(), num.doubleValue()));
}

Mind that the original number should also use the same scale as the target numbers, otherwise it will have a default scale of 2.请注意,原始数字也应使用与目标数字相同的比例,否则它将具有默认比例 2。

Personally, I'd prefer to generate a number and the delta, which has improved shrinking behaviour and will create a tuple with identical numbers more often:就个人而言,我更喜欢生成一个数字和增量,它改善了收缩行为,并且会更频繁地创建一个具有相同数字的元组:

@Provide
Arbitrary<Tuple.Tuple2<Double, Double>> closeDoubles2(@ForAll @Scale(4) BigDecimal aBigDecimal) {
    BigDecimal twoPointFive = new BigDecimal("2.5");
    return Arbitraries.bigDecimals().between(twoPointFive.negate(), twoPointFive)
                      .ofScale(4)
                      .map(num -> Tuple.of(aBigDecimal.doubleValue(), aBigDecimal.add(num).doubleValue()));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM