[英]Java units of measurement library addition and subtraction returning incorrect values
我正在使用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米。 我發現很難相信這實際上是圖書館的一個錯誤,我希望有人可以告訴我我錯過了什么。
在研究了一下后,我已經能夠重現有問題的怪異。 看起來在將Unit
傳遞給QuantityFactory時使用multiply()
或divide()
方法會產生奇怪的效果。 例如:
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
不使用這些操作,並使用MetricPrefix
枚舉的內置getConverter()
轉換為其他測量單位。
創建Quantities
的更好方法是使用Quantities.getQuantities()
添加到Beryllium提供的洞察力,我可以確認報告的行為,並已將問題跟蹤到參考實現中的錯誤。 我冒昧地報告了這個問題和我的發現以及一個提議的解決方案。
實際上, NumberQuantity
的方法doubleValue(Unit<Q>)
在轉換步驟的引擎蓋下使用,會錯誤地計算單位之間的逆變換。 這解釋了OP的觀察結果,當作為單位變換應用時,常數因子的乘法和除法似乎是相反的。
由於默認數量工廠專門返回NumberQuantity
類型的對象, 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
第二行顯示正確的轉換結果。
感謝有關如何重現該問題的詳細說明。
據報道, NumberQuantity類引起了另一個開發人員的類似問題(他通過電子郵件解釋了他的問題)所以我們知道要改進的事情,當修復完成后,我們將為RI發布服務版本。
此致,Werner
修復了JSR 363 RI的1.0.1版。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.