我正在使用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米。显然有些东西是非常错误的,这应该是3.05米。我发现很难相信这实际上是图书馆的一个错误,我希望有人可以告诉我我错过了什么。
答案 0 :(得分:4)
在研究了一下后,我已经能够重现有问题的怪异。将multiply()
传递给QuantityFactory时,使用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()
答案 1 :(得分:2)
根据Beryllium提供的见解,我可以确认报告的行为,并将问题跟踪到参考实现中的错误。我冒昧地reporting the issue和我的发现以及提议的解决方案。
实际上,在转换步骤中使用的doubleValue(Unit<Q>)
方法NumberQuantity
错误地计算了单位之间的逆变换。这解释了OP的观察结果,当作为单位变换应用时,常数因子的乘法和除法似乎是相反的。
由于默认数量工厂专门返回NumberQuantity
类型的对象,因此以这种方式创建的所有数量都会受到影响。但是,DoubleQuantity
等其他类型似乎可以正常工作。正如Beryllium在答案中所建议的那样,它们可以通过Quantities.getQuantities(<value>, <unit>)
创建。以下代码段演示了从默认工厂获得的NumberQuantity
的转换中断,但对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
其中第二行显示正确的转换结果。
答案 2 :(得分:1)
感谢有关如何重现该问题的详细说明。
据报道 NumberQuantity 类引起了另一位开发人员的类似问题(他通过电子邮件解释了他的问题)所以我们知道要改进的事情以及修复完成后我们会发布RI的服务版本。
此致 沃纳
答案 3 :(得分:1)
修复了JSR 363 RI的发布1.0.1。