首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >度量库的Java单位加减返回不正确的值

度量库的Java单位加减返回不正确的值
EN

Stack Overflow用户
提问于 2016-09-27 06:41:25
回答 4查看 1.1K关注 0票数 6

我正在使用JSR363的参考实现。我已经尝试过许多不同的方法,但我将以这个代码为例。

代码语言:javascript
复制
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,我希望有人能告诉我我错过了什么。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-09-29 00:56:53

在研究了这一点之后,我已经能够重现这些奇怪的东西了。在将multiply()divide()方法传递到QuantityFactory时,似乎会产生奇怪的效果。例如:

代码语言:javascript
复制
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。使用以下方法:

代码语言:javascript
复制
Quantity secondQuant = quantFactory.create(20.0,MetricPrefix.KILO(Units.METRE))

输出10020.0 km,这是远远不够精确的。然而,下列各点:

代码语言:javascript
复制
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()

票数 4
EN

Stack Overflow用户

发布于 2016-09-29 18:05:42

除了Beryllium提供的洞察力之外,我还可以确认报告的行为,并在参考实现中跟踪问题所在。我冒昧地选择了报告问题和我的发现,并提出了解决方案。

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

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

代码语言:javascript
复制
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)));
    }
}

这会产生

代码语言:javascript
复制
q = 5.0 m, q.to(CENTI(METRE)) = 0.05 cm
r = 5.0 m, r.to(CENTI(METRE)) = 500.0 cm

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

票数 2
EN

Stack Overflow用户

发布于 2016-09-30 11:57:34

感谢你对如何重现这个问题的详细描述。

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

你好,沃纳

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39717722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档