将负持续时间值乘以负整数时的结果无效

时间:2014-12-29 01:16:27

标签: datetime java-8 duration

Duration.ofSeconds(-4, 333333333).multipliedBy(-2)

返回PT7.333333334S,我预计结果为PT8.666666666S

似乎需要它,因为它有测试用例: http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/test/java/time/tck/java/time/TCKDuration.java#l2151

我没有看到代码在这个部分发生在哪里:

public Duration multipliedBy(long multiplicand) {
    if (multiplicand == 0) {
        return ZERO;
    }
    if (multiplicand == 1) {
        return this;
    }
    return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand)));
 }

private static Duration create(BigDecimal seconds) {
    BigInteger nanos = seconds.movePointRight(9).toBigIntegerExact();
    BigInteger[] divRem = nanos.divideAndRemainder(BI_NANOS_PER_SECOND);
    if (divRem[0].bitLength() > 63) {
        throw new ArithmeticException("Exceeds capacity of Duration: " + nanos);
    }
    return ofSeconds(divRem[0].longValue(), divRem[1].intValue());
}

private BigDecimal toSeconds() {
    return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
}

你能解释一下/为什么会这样吗?

1 个答案:

答案 0 :(得分:3)

第二个参数是调整而不是小数部分。

Duration.ofSeconds(-4, 333333333)不是-4.333333333 s 相反,它应该被理解为-4 s + 333333333 ns,它与-3.666666667 s相同。

要获得8.666666666 s作为结果,您需要使用
Duration.ofSeconds(-4, -333333333).multipliedBy(2)


它发生在计算第二个和纳秒值之和的toSeconds方法中:

private BigDecimal toSeconds() {
    return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
}