6

我正在使用 JSR363 的参考实现。我已经尝试了很多变体,但我会以这段代码为例。

ServiceProvider provider = ServiceProvider.current();
QuantityFactory<Length> lengthFactory = provider.getQuantityFactory(Length.class);
Quantity<Length> first = lengthFactory.create(5, Units.METRE.divide(100.0));
Quantity<Length> second = lengthFactory.create(3, Units.METRE);
System.out.println(second.add(first));

这将打印 503.0 m。显然有些地方很不对劲,这应该是 3.05 m。我很难相信这实际上是图书馆的一个错误,我希望有人能告诉我我错过了什么。

4

4 回答 4

4

在研究了一下之后,我已经能够重现有问题的奇怪之处。似乎在将 a 传递给 QuantityFactory 时使用multiply()divide()方法Unit会产生奇怪的效果。例如:

Quantity firstQuant = quantFactory.create(10.0,Units.METRE)
Quantity secondQuant = quantFactory.create(20.0,Units.METRE.divide(10.0))
System.out.println(secondQuant.add(firstQuant))

输出以下内容:20.5 dm. 即使使用MetricPrefix,这似乎是设置非基本 SI 单位的默认方法,它似乎也会生成极其不准确Units的 。使用以下内容:

Quantity secondQuant = quantFactory.create(20.0,MetricPrefix.KILO(Units.METRE))

输出10020.0 km远不准确。但是,以下内容:

Quantity firstQuant = quantFactory.create(10.0,Units.METRE)
Quantity secondQuant = quantFactory.create(20.0,Units.METRE)
System.out.println(secondQuant.divide(10.0).add(firstQuant))

输出12.0 m,这显然是正确的答案。

老实说,最好的解决方案是在创建时不使用这些操作,Quantity并使用内置getConverter()MetricPrefix枚举转换为其他度量单位。

更好的创建方法Quantities是使用Quantities.getQuantities()

于 2016-09-29T00:56:53.593 回答
2

除了 Beryllium 提供的洞察力之外,我还可以确认报告的行为,并将问题追溯到参考实现中的错误。我冒昧地报告了这个问题和我的发现以及建议的修复。

实际上,在转换步骤中使用的方法会错误地计算单位之间的逆变换doubleValue(Unit<Q>)NumberQuantity这解释了 OP 的观察,即当作为单位变换应用时,常数因子的乘法和除法似乎是相反的。

由于默认数量工厂专门返回类型为 的对象,NumberQuantity因此以这种方式创建的所有数量都会受到影响。但是,其他类型DoubleQuantity似乎可以正常工作。正如 Beryllium 在回答中所建议的那样,它们可以通过Quantities.getQuantities(<value>, <unit>). 以下代码片段演示了NumberQuantity从默认工厂获得的 a 的转换中断,但对于 a 可以正常工作DoubleQuantity

package test.jsciunits;

import javax.measure.spi.ServiceProvider;
import javax.measure.Quantity;
import javax.measure.quantity.Length;
import javax.measure.spi.QuantityFactory;
import tec.units.ri.quantity.Quantities;
import static tec.units.ri.unit.Units.*;
import static tec.units.ri.unit.MetricPrefix.*;

public class JScienceUnits {
    public static void main(String[] args) {
        ServiceProvider provider = ServiceProvider.current();
        QuantityFactory<Length> lengthFactory = provider.getQuantityFactory(Length.class);

        Quantity<Length> q = lengthFactory.create(5.0, METRE);
        Quantity<Length> r = Quantities.getQuantity(5.0,  METRE);

        System.out.println("q = " + q + ", q.to(CENTI(METRE)) = " + q.to(CENTI(METRE)));
        System.out.println("r = " + r + ", r.to(CENTI(METRE)) = " + r.to(CENTI(METRE)));
    }
}

这产生

q = 5.0 m, q.to(CENTI(METRE)) = 0.05 cm
r = 5.0 m, r.to(CENTI(METRE)) = 500.0 cm

其中第二行显示正确的转换结果。

于 2016-09-29T18:05:42.403 回答
1

感谢您详细说明如何重现该问题。

另一位开发人员(他通过电子邮件解释了他的问题)报告了NumberQuantity类导致了类似的问题,因此我们知道需要改进的地方,当修复完成时,我们将为 RI 发布服务版本。

问候,维尔纳

于 2016-09-30T11:57:34.093 回答
1

已在 JSR 363 RI 的1.0.1版中修复。

于 2016-10-06T20:53:41.157 回答