我正在使用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米。我很难相信这真的是图书馆里的一个bug,我希望有人能告诉我我错过了什么。
发布于 2016-09-29 00:56:53
在研究了这一点之后,我已经能够重现这些奇怪的东西了。在将multiply()或divide()方法传递到QuantityFactory时,似乎会产生奇怪的效果。例如:
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() of MetricPrefix枚举将其转换为其他度量单位。
创建Quantities的更好方法是使用Quantities.getQuantities()
发布于 2016-09-29 18:05:42
除了Beryllium提供的洞察力之外,我还可以确认报告的行为,并在参考实现中跟踪问题所在。我冒昧地选择了报告问题和我的发现,并提出了解决方案。
实际上,在转换步骤中使用的doubleValue(Unit<Q>) of NumberQuantity方法错误地计算了单元之间的逆转换。这就解释了OP观察到,当作为单位变换应用时,常数因子的乘法和除法似乎是相反的。
由于默认数量工厂只返回NumberQuantity类型的对象,因此以这种方式创建的所有数量都会受到影响。然而,像DoubleQuantity这样的其他类型似乎工作正常。正如铍的答案所建议的那样,它们可以通过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其中第二行显示正确的转换结果。
发布于 2016-09-30 11:57:34
感谢你对如何重现这个问题的详细描述。
据报道,NumberQuantity类由另一个开发人员(他通过电子邮件解释了他的问题)引起了类似的问题,因此我们知道需要改进的地方,当修复完成后,我们将为RI发布一个服务版本。
你好,沃纳
https://stackoverflow.com/questions/39717722
复制相似问题